关于如何在VSCode环境基于STM32Cube插件使用DapLink进行调试的研究

1. 背景与动机

七月份电赛就要开打了,最近也是入手了两块天猛星的ti板子,想着先熟悉一下ti芯片的开发,顺手就购入了心心念念的DapLink(逻辑分析仪二合一)。本人虽然蛮久时间没有用过keil了,但是偶尔用上一次,令人心酸的代码补全和代码提示实在是让代码体验苦不堪言。于是跟着keysking的教程,我将整个开发工具链迁移到了我有较长使用经历的VSCode,并打算后续将包括嵌入式开发的整个环境迁移到Linux上去。总之就是这样,我虽然能够成功在VSCode使用STlink进行调试,但是ST插件没有对DapLink的支持,无法用我新买的DapLink进行调试实在是不够优雅,于是我踏上了对调试环境艰辛(也说不上)的探索。

2. 逻辑梳理

想要理解如何为什么要使用DapLink以及如何使用DapLink,就需要理清楚嵌入式开发和调试的整个逻辑链条。趁着这个机会,我也是完完整整地梳理了一遍开发流程,让我对嵌入式开发的理解更上了一层楼。

核心组件与职责

  • CMake:用于管理编译流程,指挥编译器生成elf文件,这个文件包含芯片的机器码和其他调试信息
  • ARM-GCC:编译器,用于连接源程序,生成可执行文件(对于芯片来说)
  • .elf文件:可执行文件,包含机器码、调试信息、符号表
  • OpenOCD:调试服务器,通过接受gdb请求并翻译成对应内存指令,传输到DapLink,驱动DapLink硬件进行芯片的读写操作
  • CMSIS-DAP 协议:OpenOCD支持的协议,由ARM公司官方制定的标准化协议,规定了调试软件和硬件的通信协议
  • GDB:调试客户端,通过接受用户在PC上的调试指令,像服务端发送请求,由OpenOCD创建的服务端会接受请求并下发到DapLink,进而完成内存读写操作
  • VSCode + STM32Cube插件:提供开发环境,提供面向用户的调试接口

3. 环境搭建

  1. 下载VSCode、STM32CubeMX等
  2. 在插件市场安装对应插件(参考keysking教程(爽!手把手教你用VSCode开发STM32【大人,时代变啦!!!】)
  3. 下载OpenOCD,将可执行文件目录添加到Path,可在终端运行openocd --version判断是否安装正确
  4. 使用DAPLink连接目标芯片,运行openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg判断是否识别正确,配置文件参数须根据实际连接目标决定
  5. 配置VSCode launch.json,如果没有就自己在运行与调试(侧边栏)创建一个:
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
29
30
31
32
"configurations": [
{
"type": "stgdbtarget",
"request": "launch",
"name": "STM32Cube: Launch Generic GDB Server",
"origin": "snippet",
"cwd": "${workspaceFolder}",
"preBuild": "${command:st-stm32-ide-debug-launch.build}",
"program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
"gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
"deviceName": "${command:st-stm32-ide-debug-launch.get-device-name}",
"deviceCore": "${command:st-stm32-ide-debug-launch.get-core-name}",
"deviceTrustzone": "TZ-disabled", // 此处修改,按需求改为指定设备,不改应该也没问题
"serverExe": "openocd.exe", // 此处修改,这里改成ocd文件名
"serverParameters": [ // 此处修改
"-f", "interface/cmsis-dap.cfg", // 指定接口为 CMSIS-DAP (DAPLink)
"-f", "target/stm32f1x.cfg" // 指定目标设备,我这里是f103c8t6所以写得f1x,具体可以参考openocd目录里的配置文件
],
"serverHost": "localhost", // 这里修改,Openocd会把gdb服务器开在本地端口3333
"serverPort": "3333", // 这里填端口
"serverCwd": "E:\\xpack-openocd-0.12.0-7\\bin", // 这里改成ocd目录
"runEntry": "main",
"imagesAndSymbols": [
{
"imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
"imageOffset": "",
"symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
"symbolOffset": ""
}
]
},
]

4.踩坑记录

一号小坑:GDB server is undefined

现象:
bound doStepSettingsValidation Failed: GDB server is undefined, see serverExe && serverCwd attributes
原因: VSCode的STM32Cube插件找不到openocd命令,即使命令行中可以正常运行。此时并未配置ocd路径,只在server一栏中填入了openocd
解决方案: 同时指定路径和程序名字

1
2
"serverExe": "openocd.exe",
"serverCwd": "E:\\xpack-openocd-0.12.0-7\\bin"

二号小坑:deviceTrustzone 值不被接受

现象:
值不被接受。有效值: "Secure", "Non-secure", "Secure-only", "TZ-disabled"
原因: deviceTrustzone 字段有严格的枚举值限制。
解决方案: 感觉不是大问题,还没有试过没改会不会造成影响,反正TZ-disabled对应STM32设备,直接改成这个就行

1
"deviceTrustzone": "TZ-disabled"   // 普通 STM32 芯片

6. 一些FAQ

Q1:OpenOCD 支持哪些调试器?

支持 CMSIS-DAP 协议的所有调试器,包括:

  • DAPLink(各种国产开发板上的调试器)

  • Sipeed SLogic Combo 8(逻辑分析仪+DAPLink二合一)

  • 正点原子、野火等开发板自带的 DAPLink

Q2:为什么 .elf 文件不能直接烧录?

需要有软件(如 OpenOCD、ST-Link Utility)将 .elf 解析后,通过调试器(硬件)以 SWD/JTAG 协议写入芯片 Flash。OpenOCD 扮演的就是这个“翻译官”角色。

可以。将 serverParameters 中的接口文件改为:

1
"-f", "interface/stlink.cfg"

Q4:如何确认芯片型号对应的 target 配置文件?

查看 OpenOCD 安装目录下的 scripts/target/ 文件夹:

  • STM32F103 系列 → stm32f1x.cfg

  • STM32F407 系列 → stm32f4x.cfg

  • STM32H743 系列 → stm32h7x.cfg

Q5:launch.json 中的 ${command:…} 是什么?

这是 VSCode 的命令变量,由插件动态计算。例如:

  • get-gdb-executable:自动定位 arm-none-eabi-gdb 的路径

  • get-projects-binary-from-context1:自动获取项目编译生成的 .elf 文件路径

7. 总结

真是一场酣畅淋漓的调试,现在我可以通过DAPLink对任何芯片进行下载和调试了哈哈哈哈。