使用VSCode开发Cortex-M系列芯片

最近实在是受不了那些基于eclipse的IDE来开发arm了,界面太丑,而且自动补全功能不好用,于是准备使用vscode加上一系列的开源工具链来开发。其实也可以使用VisualGDB+Visual Studio来开发,但是我觉得还是太重了。

2023/08/12更新,现在ST官方推出了vscode的插件了,可以直接开发STM32了,具体内容详见文末更新章节

使用的工具

  • Visual Studio Code
  • Cmake
  • GNU Arm Embedded Toolchain
  • OpenOCD
  • Cmake tool(VSC的插件)
  • Cortex-Debug(VSC的插件)

硬件介绍

这里我使用的是NXP的FRDM-KL02Z开发板,这个开发板使用板载的OpenSDA调试器来调试,自带的OpenSDA支持三种调试接口,分别是PEMicro,CMSIS-DAP,JLink。此外,它还支持将bin文件直接拖拽进虚拟出来的储存设备的方式来下载程序。使用不同的调试接口需要给OpenSDA刷入不同的固件,关于固件的详细信息可以参考NXP的网站

我在这里使用的是CMSIS-DAP的接口,主要是因为PEMicro和Jlink的GDBServer不好找(不开源,不想用盗版等原因)。

关于SDK,这里我使用的NXP的MCUXpresso。用MCUXpresso Config Tools能够生成适用于各种开发平台的工程,这里使用的是gcc工具链,它自动使用cmake来管理工程。

开发流程

1
2
3
4
5
6
7
Xpresso=>operation: 生成CMake工程
Config=>operation: 在VSC中配置Cmake
Build=>operation: 编译
ConfigDebug=>operation: 配置调试器
Debug=>operation: 调试

Xpresso->Config->Build->ConfigDebug->Debug

由此可见过程可以分为编译和下载调试两部分。编译部分使用CMake+GNU toolchain来生成elf文件。下载调试部分使用GNU toolchain中的GDB来调试,使用OpenOCD来做GDBServer。

配置CMake

由MCUXpresso生成的工程自带CMakeLists.txttoolchain file,我们只需要指定toolchain file给vsc的cmake插件就可以自动配置必要的编译环境了,我最开始还走了一些弯路,想着手动配置编译器。根据CMake的文档.vscode文件夹中创建cmake-kits.json文件,并输入以下内容

1
2
3
4
5
6
7
8

//cmake-kits.json
[
{
"name": "arm-gcc",
"toolchainFile": "${workspaceFolder}/armgcc.cmake"
}
]

然后还需要指定generator的类型,在工程的.vscode/settings.json中指定MinGW Makefiles。由于这个toolchain file中使用了ARMGCC_DIR这个变量,所以要么在系统的环境变量中添加,要么在settings.json中一并添加。

1
2
3
4
5
6
7
8
//settings.json
{
"cmake.generator": "MinGW Makefiles",
"cmake.environment": {
"ARMGCC_DIR": "C:\\Program Files (x86)\\GNU Arm Embedded Toolchain\\9 2020-q2-update\\"
},
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}

之后在选择cmake configuration的时候就会出现刚刚添加的选项,选择这个选项就好了,不要自己在settings.json中配置编译器,prefix,args等等!

完成上述配置之后,应该直接编译就能生成.elf文件了。上述操作等效于以下命令:

1
2
cmake -DCMAKE_TOOLCHAIN_FILE="armgcc.cmake" -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=debug  .
mingw32-make

配置调试

关于Cortex-M系列的调试,这里也是用的GDB+GDBServer的模式,GDB对应的GNU工具链中的GDB,使用OpenOCD作为GDBServer。其实本可以在task.json中手动配置并启动OpenOCD,然后在launch.json中配置并启动GDB来下载调试,但是这样过程有些繁琐。好在我发现了Cortex-Debug这个插件,可以帮助我们完成上诉操作。由上述所述,调试配置包含启动OpenOCD和启动GDB两个部分,首先需要在全局settings.json中指定Cortex-Debug需要的GDB和openOCD的位置。之后创建launch.json输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//launch.jsom
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "./build/Debug/hello_world.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"configFiles": ["interface/cmsis-dap.cfg","target/klx.cfg"],
"searchDir": ["C:\\ProgramFiles\\OpenOCD\\share\\openocd\\scripts"],
"runToMain": true
}
]
}

可能不好理解的是servertype,configFilessearchDir三个字段。这都是启动openOCD相关的指令,等效命令行为:

1
openocd.exe -s "C:\ProgramFiles\OpenOCD\share\openocd\scripts" -f interface/cmsis-dap.cfg -f target/klx.cfg

openocd是使用tcl脚本语言来工作的。-f后面的两个参数分别指定了使用的调试接口和芯片类型,由于没有对应的文件这里kl02z使用klx.cfg;-s参数指定了搜索这些tcl脚本的位置,其实就是openocd的安装目录。

之后直接启动调试,就能自动下载并开始调试了。

2023/08/12更新

现在STM32官方提供了vscode的支持,可以直接使用官方的插件进行开发了。可以下载使用STM32 VS Code Extension 来绕过上述过程,注意仅限STM32系列。NXP也提供了类似的插件,但是我没有使用过,可以自行尝试MCUXpresso for VS Code

但值得注意的是这个插件需要依赖STM32CubeIDE或者STM32CubeCLT,然而在插件中将这些工具的安装目录给写死了,所以推荐将这些工具安装在默认位置,否则可能会出现找不到工具链的情况。

如果强迫症发作一定要修改安装目录,那么在后续的开发和调试过程中需要手动修改一些配置文件,这里给出一些参考:

  • 修改工程目录下cmake文件夹中(该文件夹由插件自动生成)的gcc-arm-none-eabi.cmake文件,将其中的WINDOWS_ST_CLT_PATH变量修改为自己的安装目录。例如 set(WINDOWS_ST_CLT_PATH "C:/ProgramFiles/STM32CubeCLT/GNU-tools-for-STM32/bin/")

  • 修改launch.json中的miDebuggerPathdebugServerPath为自己的可执行文件,修改debugServerArgs中的--stm32cubeprogrammer-path参数为自己的安装目录。

如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}",
"program": "${command:cmake.launchTargetPath}",
"MIMode": "gdb",
"miDebuggerPath": "C:/ProgramFiles/STM32CubeCLT/GNU-tools-for-STM32/bin/arm-none-eabi-gdb.exe", //这里修改为自己的安装目录
"miDebuggerServerAddress": "localhost:3333",
"debugServerPath": "C:/ProgramFiles/STM32CubeCLT/STLink-gdb-server/bin/ST-LINK_gdbserver.exe", //这里修改为自己的安装目录
"debugServerArgs": "--stm32cubeprogrammer-path C:/ProgramFiles/STM32CubeCLT/STM32CubeProgrammer/bin --swd --port-number 3333", //这里修改为自己的安装目录
"serverStarted": "Waiting for connection on port .*\\.\\.\\.",
"stopAtConnect": true,
"postRemoteConnectCommands": [
{
"text": "load build/debug/build/test2.elf"
}
],
"logging": {
"engineLogging": true
},
"preLaunchTask": "Build"
}
]
}

如果出现Error in initializing ST-LINK device.Reason: ST-LINK firmware upgrade required. Please upgrade the ST-LINK firmware using the upgrade tool.错误,可能是需要升级ST-LINK固件,可以参考这里


EOF