VSCode开发STM32单片机--CMake构建
目录
介绍:
本方案采用CMake配置整个项目文件,用Ninja来构建这些文件(编译和链接),然后使用OpenOCD将生成的程序下载到单片机;配置、编译、下载这三个步骤,只需点击按键就能实现;建议先看完大体过程,再逐步去实现。
最终呈现的效果图:

下面将讲解实现该效果的步骤;在搭建过程中,出现问题,可以跳转到后面的问题点,看有没有该问题点的解决方法。
一、软件安装及环境适配
使用到的软件及工具有:STM32CubeMX(默认已装好)、VSCode(默认已装好)、CMake、Ninja、arm-none-eabi、OpenOCD、clang(主要作用是提升代码编辑体验),除了VSCode软件,上面的这些软件都有放在下面网盘里,不想在网盘下的,可以通过下载链接来下载。
百度网盘地址:https://pan.baidu.com/s/1b6jrrQOQUSatzGWxeNVvOA
提取码: htj2
1、工具链安装
只需要将已经编译好的软件压缩包解压出来就行。
(1)CMake安装:
CMake 下载链接
文件下载好,解压出来即可,如下图:
(2)Ninja安装:
Ninja 下载链接
文件下载好,解压出来即可,如下图:
(3)arm-gnu-toolchain安装:
arm-none-eabi 下载链接
这个文件有点大,下载过程中,可以先往下看,配置其他工具。
文件下载好后,解压出来即可,如下图:
(4)OpenOCD安装:
OpenOCD 下载链接
文件下载好,解压出来即可,如下图:
(5)clang安装:
clang 下载链接
这个文件也是有点大,下载过程中,可以先往下看,去配置环境变量。
注意:这个文件被压缩了两层,下载好后,需要解压两次,步骤如下图:
2、配置环境变量
建议将这些工具放在同一个文件夹下,我这里是统一放ARMToolChain这个文件夹下。
然后将这些工具加到环境变量里面,步骤如下;
在搜索窗口输入“环境变量”,点击匹配出来的程序,如图:
点击底部的“环境变量”,如图:
双击用户变量或者系统变量里的Path,如图:
点击新建,添加路径,如图:
工具的路径复制方法:
Ninja这个工具的路径是到包含ninja.exe文件的这个文件夹,其他工具的路径是到第一个bin文件夹就行,添加完成记得点确定。
验证是否添加成功的方法,打开Windows终端,输入其查询版本命令,看终端是否输出其版本。
分别输入命令:
cmake --version
ninja --version
arm-none-eabi-gcc --version
openocd --version
clangd --version
各个查询结果如下各图:




这些工具的环境变量都添加完成后,OpenOCD这个工具还需要在在环境变量里添加一个变量。
变量名是:OPENOCD_SCRIPTS
变量值是:OpenOCD里面的scripts这个文件夹下,进入share文件夹->进入openocd文件夹->进入scripts文件夹。
添加新的变量步骤,如下;
在用户变量或者系统变量点击新建,如图:
添加变量名及变量值,如图:
添加成功后,效果如图:
还不知道路径的,可以参考我的路径找找看(去到解压出来的OpenOCD文件里):
我的路径:D:\ARMToolChain\OpenOCD-2026\share\openocd\scripts
这个变量添加完成,都点击确定后,所有的环境变量就已经配置完成了。
二、STM32CubeMX生成CMake文件:
这里通过STM32CubeMX生成的CMake文件,就不用自己动手写CMake文件了,先将演示项目跑通,跑通之后可以再去研究细节。
这里演示我配置的芯片是STM32F103c8t6,适用F1系列的,其他系列的,根据实际芯片来做更改;
Debug选项:选Serial Wire
外设配置和时钟配置与平常使用Keil时的一样。
在后面项目管理配置主要更改的有两处地方,如下图:
这样生成的项目文件就可以用CMake来构建了,这里建议项目名称和我的一样,定为:cmakeDome
因为后面提供的json文件内容就是这个项目名称,后面就不用再改settings文件里的项目名称。
现在就可以用VSCode来编译和下载STM32CubeMX生成的代码了:
将STM32CubeMX生成的项目文件夹在VSCode软件中打开:
参考操作1:直接到该文件夹下然后右击,弹出的选项中,选择“通过Code打开”;
参考操作2:在VSCode里选择“打开文件夹”,然后到该项目的主文件夹里,然后点击打开文件夹。
第一次打开,VSCode会提示是否信任该文件夹,点信任,功能才不受限,然后会停留在"欢迎"界面,随便点一个文件,欢迎界面就会被覆盖了。
操作1步骤如下图:
打开后的参考图片如下:
然后在终端输入命令来实现操作,没看到终端的,可以点击顶部的“查看”,然后点击“终端”,就能在底部看到终端了;
在终端输入命令:cmake --preset Debug
上面构建完成后,在终端输入命令:ninja -C build/Debug
这里编译完成的可烧录的文件是后缀为.elf的文件,是在Debug文件夹下,名称是和STM32CubeMX里我们定的项目名称一样。
确定编译成功后,接下来就是下载elf文件到单片机上了,这里我使用的ST-Link调试器,将单片机和电脑连接好之后,在终端输入命令:
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c “program ./build/Debug/cmakeDome.elf verify reset exit”
到这里,说明配置、编译、下载没问题了,下面我们的目的就是将这三个命令配置成三个按钮,只需点击一下,终端就会自动执行命令。
三、VSCode环境配置
1、安装VSCode插件
需要安装的插件,如图:
2、建立VSCode任务
在该项目下新建.vscode文件夹,然后再新建tasks.json文件,然后把需要执行的三条命令分别写成三个任务。
tasks.json文件的内容参考如下:
{
"version": "2.0.0",
"tasks": [
{
"label": "CMake Configure",
"type": "shell",
"command": "cmake",
"args": ["--preset", "${config:myproject.buildType}"], // 使用settings.json中定义的构建类型
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Build",
"type": "shell",
"command": "cmake",
"args": ["--build", "--preset", "${config:myproject.buildType}"], // 使用settings.json中定义的构建类型
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Flash with OpenOCD",
"type": "shell",
"command": "openocd",
"args": [
"-f", "interface/stlink.cfg",
"-f", "target/stm32f1x.cfg",
"-c", "program ./build/${config:myproject.buildType}/${config:myproject.projectName} verify reset exit"
// 使用settings.json中定义的构建类型和项目名称
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
图片说明如下:
tasks.json文件写完成后,执行任务的方法可以看下面的图,知道执行步骤就行,建议这里先不执行。
如果执行了任务,会弹出报错信息,如下图,因为tasks.json文件里我是用了可配置的变量来代替了具体的文件夹名称和文件名称,目的是当编译出来的文件夹名称和文件名有改动时,我们只需要改动更少的地方;所以这里弹出来的信息可以忽略,继续往下配置。
3、设置任务按钮
在.vscode文件夹下,新建一个settings.json文件,
里面的内容就是将按钮对应到任务及配置tasks文件里的可配置变量;settings.json文件内容如下:
{
// 根据需要来修改的两处变量
"myproject.buildType": "Debug", // 构建代码类型,可以是 Debug 或者 Release
"myproject.projectName": "cmakeDome.elf", // 生成的项目文件,必须与 CMakeLists.txt 中的项目名称一致
"VsCodeTaskButtons.tasks": [
{
"label": "$(wrench) Configure",
"task": "CMake Configure",
"tooltip": "Run CMake Configure Task"
},
{
"label": "$(tools) Build",
"task": "Build",
"tooltip": "Run Ninja Build Task"
},
{
"label": "$(chip) ST-Link Download",
"task": "Flash with OpenOCD",
"tooltip": "Run Flash with OpenOCD Task"
},
],
"clangd.checkUpdates": false,
}
图片说明如下:
4、配置、编译、烧录代码
settings文件完成后,就可以点击带Configure的扳手图标,来进行配置了,等终端执行完成,此时会生成一个build文件夹,展开这个build文件夹,里面就是CMake构建出来的文件,如图:
构建完成后,就可以点击带Build的铲子图标,来进行编译和链接,完成后会生成一个elf文件,如图:
编译完成后,用stlink烧录器将开发板和电脑连接好后,点击带ST-Link Download的芯片图标,等待烧录完成即可,如下图:
注:tasks文件里配置的是stlink烧录器来下载,不同的烧录器需要做更改。
烧录完成后,这套环境就能配置、编译、烧录stm32单片机了,后面的主要内容就是实现代码中变量、函数跳转及程序调试功能的步骤了。
(已烧录成功的可以跳过这段)注意:如果之前在STM32CubeMX里填写的项目名称和我的不一样的,那烧录前先在settings.json文件里将文件变量改成和生成elf文件名称一样,保留elf后缀,然后再烧录,如图:
5、配置调试文件
在.vscode文件夹下新建一个launch.json文件,用于配置调试环境,launch.json文件内容如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with OpenOCD",
"type": "cortex-debug",
"request": "launch",
"servertype": "openocd",
"cwd": "${workspaceFolder}",
// 使用settings.json中定义的构建类型和项目名称来指定可执行文件路径
"executable": "${workspaceFolder}/build/${config:myproject.buildType}/${config:myproject.projectName}",
"runToEntryPoint": "main",
"toolchainPrefix": "arm-none-eabi",
"svdFile": "${workspaceFolder}/STM32F103.svd",
"configFiles": [
"interface/stlink.cfg",
"target/stm32f1x.cfg"
],
//连接后先复位并暂停
"preLaunchCommands": [
"monitor reset halt"
],
"showDevDebugOutput": "raw"
}
]
}
保存launch.json文件内容后,确保elf文件已经生成,就可以调试了,步骤如图:
第一次启动调试时会弹出一个错误,报错弹窗见下面的图;
这个错误的解决方法有三种:
1、就是启动调试时也对开发板进行复位;
2、点“取消”后再重新启动调试,因为launch文件里有包含复位的操作;
3、将插件Cortex-Debug回退到1.4.4版本。
这三种选一种就能让单片机进入调试模式了。
成功进入调试模式的界面如下图:
6、优化编辑体验(clangd)
通过clangd来实现变量和函数的跳转及提示;进入clangd插件的设置选项里,在Clangd:Arguments项下有个添加项,点击这个“添加项”,
然后输入:–compile-commands-dir=${workspaceFolder}/build/Debug
点击确定,步骤见下图:
配置完clangd后,重启clangd server,步骤见下图:
重启clangd server后,在下方的问题窗口,就没有提示错误了,可以试试看函数和变量是否可以跳转到定义处,输入函数或变量时是否有自动补全提示。
到这里,stm32单片机项目中的代码编辑、编译、烧录、调试;已经完全可以在vscode上实现了。
下面的内容就是在这个基础上将我们自己编写的头文件、源文件添加到CMakeLists中,让其将这些文件配置进去。
四、整体项目讲解
1、项目主要文件介绍
主要关注的文件是主CMakeLists.txt文件,项目新增的头文件和源文件要在里面进行添加,主要文件说明如图:
2、添加头文件和源文件
实际开发时,会有额外的头文件和源文件,将这些文件路径配置到主CMakeLists.txt文件内容即可,具体修改位置如下图:
3、Debug版和Release版主要区别
在STM32CubeMX生成的CMakePresets.json文件中提供了两个配置选项,分为Debug和Release,其内容如下:
不同的选项生成的文件会有一些不同,这里主要是关注的地方有两处,生成的文件夹名称会不同,并且编译生成的烧录文件所用内存大小不同;
Debug选项:会将配置和编译好的文件都放在Debug文件夹下,即build/Debug路径,烧录的程序占用内存较多,因为含调试信息。
Release选项:会将配置和编译好的文件都放在Release文件夹下,即build/Release路径,烧录的程序占用内存较少,因为不含调试信息。
相同代码烧录文件内存对比如图:
可以通过settings.json的可配置变量来指定生成哪个版本,修改位置如下:
由于配置选项不一样,CMake生成的文件夹不同,为了clangd都能索引,可以将这两种配置的路径都添加上,这样不管生成哪个版本,clangd都能找到索引文件,修改如图:
4、添加svd文件
这里添加svd文件主要目的是为了调试时,可以查看寄存器的值,在提供的launch.json文件中,有添加svd文件的内容,指定路径是主文件夹下的的svd文件,根据实际用的来进行修改,如图:
svd文件添加后,进入调试模式,点开调试窗口最下方的“XPERIPHERALS”窗口,就能看到svd文件里描述的寄存器了,点开相关外设,就能看到其寄存器的值,如图:
5、git bash管理文件
(注:这里是为了练习Linux的文件管理命令)要用git bash,首先要有装git,并且配置环境变量,这里是在PowerShell里运行git bash,然后使用linux的命令来管理文件,不仅能练习linux命令,个人觉得还比在vscode里管理文件快多了。如图:
stm32各个芯片的svd文件和上面解析的这个项目代码,都在上面分享的百度网盘里了。
五、可能出现的问题点
1、CMake版本低的问题
由于CMakeLists.txt文件开头就要求了CMake版本不低于3.22版本;这里提供两种解决办法:
第一种:就是将CMakeLists.txt文件开头要求的CMake版本修改为当前通过终端查询到的版本,主CMakeLists.txt文件和子CMakeLists.txt文件都要修改。
修改处如图:
第二种:安装高于要求版本的,但如果是已经安装了高版本的CMake,但终端查到的是低版本的,可以在终端输入:where cmake命令,来查看有哪个地方也配置了cmake
的环境变量,然后到环境变量里,将低版本路径移到高版本路径的下面,点击确定后,重新打开终端程序cmake版本,就能查到安装的高版本了。操作如图:
2、clangd不能索引问题
如果确定代码编写没问题,但还会报错,可能就是clangd没有找到索引文件compile_commands.json文件。
1、如果没有compile_commands.json文件的话,点下配置按钮,这个文件就生成了,然后在重启clangd server。
2、如果有compile_commands.json文件,重启clangd server还是会报错,看下clangd:Arguments配置的路径是否正确,配置如下图:
3、程序烧录问题
烧录程序时,有错误提示:不能打开elf文件,错误提示如图:
检查有没有生成elf文件,如果有elf文件,检查settings文件里定义的文件名称是否和这个elf文件名称相同,检查点如图:
如果文件名称对得上,那可能是使用的调试器或者芯片型号与配置的不符,可以在tasks文件检查配置的是否和实际用的对的上,检查点位置如图:
4、调试问题
第一次启动调试时或者调试间隔长就会弹出一个错误,报错弹窗见下面的图:
这个错误的解决方法有三种:
第一种:就是启动调试时也对开发板进行复位。
第二种:点“取消”后再重新启动调试,因为launch文件里有包含复位的操作,可以多试几次。
第三种:将插件Cortex-Debug回退到1.4.4版本。
致谢
感谢B站up主:ControlCoreX,他对整个流程专业的讲解,才使我有信心来搭建这环境。
他的B站视频:【STM32终极开发环境搭建教程01】对使用VSCode开发STM32的介绍
感谢开发这些软件和工具的个人、团体及公司。
感谢DeepSeek(背后的团队),起初是打算不用STM32CubeMX来生成CMake的配置文件的,所以和deepseek多次的问答下,也搭建出来了,但后面还是觉得开发stm32单片机用STM32CubeMX生成的会方便点;之前的过程让我对整个流程有了更清晰的认识。
感想:起初觉得STM32CubeMX生成的简单,没必要写教程,但想想,如果不分享简单的教程,那么用这个环境做开发的人就不会多,那终究都是自己的自娱自乐;也当作一个记录。
注意:由于本人技术有限,该教程有不足和不妥之处,还望各位朋友海涵。
更多推荐
所有评论(0)