cortex-debug+openocd是vscode调试stm32最稳定可控的组合,需确保configfiles路径正确、executable指向带dwarf信息的未strip elf文件,并配置runtoentrypoint及验证硬件连接。

cortex-debug 插件配合 openocd 是目前 VSCode 调试 STM32 最稳定、最可控的组合。Keil 或 STM32CubeIDE 的图形化调试虽然开箱即用,但底层封装太深,出问题时很难定位;而 VSCode + cortex-debug 把调试链路的关键环节(GDB Server、目标连接、符号加载)全部暴露出来,调不通的时候你能看到具体卡在哪一步。
launch.json 中 configFiles 路径必须指向真实存在的 OpenOCD 配置文件
常见错误是直接复制网上的配置,写成 "configFiles": ["interface/stlink.cfg"],结果报错:OpenOCD: Can't find interface/stlink.cfg。
这是因为 openocd 启动时默认只在当前工作目录下找配置文件,不会自动搜索安装目录里的 tcl/ 子目录。
- 确认你的
openocd安装路径,比如D:\toolchain\openocd\bin - 进入该目录,查看是否存在
share/openocd/scripts/interface/stlink.cfg(Windows 下路径分隔符用/或\均可,但 JSON 里推荐用/) - 在
launch.json中改用绝对路径或相对路径(从openocd可执行文件所在目录算起):"configFiles": [ "share/openocd/scripts/interface/stlink.cfg", "share/openocd/scripts/target/stm32f4x.cfg" ]
- 如果你用的是 FireDAP 或 CMSIS-DAP,别硬套
stlink.cfg,要换interface/cmsis-dap.cfg,否则 OpenOCD 启动就失败,VSCode 连“正在启动服务器”这句日志都不会输出。
executable 必须指向带调试信息的 .elf 文件,且编译时不能 strip
很多用户用 Makefile 编译后发现断点灰掉、变量显示 <optimized out></optimized>,根本原因是:
- 编译命令里加了
-Os或-O2且没关优化对调试的影响 - 链接后执行了
arm-none-eabi-strip,把 ELF 中的 DWARF 调试段全删了
确保你的 Makefile 或构建脚本中:
- CFLAGS 包含
-g3 -O0(开发阶段不要用-Os) - LDFLAGS 不含
--strip-all或类似选项 - 最终生成的
build/demo.elf文件大小应在几百 KB 以上(ls -lh build/*.elf可粗略判断) - 在终端运行
arm-none-eabi-readelf -w build/demo.elf | head -n 20,能看到Abbrev Table、Line Number Statements等 DWARF 段才说明调试信息完整
launch.json 中的 executable 字段必须精确匹配这个未 strip 的 ELF 路径,比如:
"executable": "${workspaceFolder}/build/${workspaceFolderBasename}.elf"
断点不命中?先检查 runToEntryPoint 和复位行为
你打了个断点在 main 函数第一行,按 F5 启动后程序直接跑飞、LED 开始闪烁——这不是断点失效,是 cortex-debug 默认没停在 main,而是从复位向量开始执行。
- 设置
"runToEntryPoint": "main"确保 GDB 自动在进入main前暂停 - 但更关键的是:有些芯片(如 STM32F103)的启动文件会先执行
SystemInit(),而它内部可能有延时或外设初始化,导致你还没来得及看寄存器,程序已跑过断点
这时建议:
- 把断点打在
Reset<em>Handler</em>(在startup*.s里),确认是否能停住 - 若能停住,再手动单步(F10)进
main,观察哪一行跳出了调试控制 - 若连
Reset_Handler都不停,大概率是 OpenOCD 连接成功但 GDB server 没正确 attach,检查servertype是否为"openocd",且openocd进程是否真在后台运行(任务管理器里搜openocd.exe)
真正卡住的地方往往不是配置语法,而是硬件握手细节:ST-Link 固件版本太老、SWD 引脚被误配为 GPIO、目标板供电不足导致 SWCLK 信号畸变。这些不会报错,只会让调试器“静默失败”——看起来一切就绪,但就是不响应。每次怀疑是软件问题前,先用 openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "init; reset halt; dump_image ram.bin 0x20000000 0x1000; exit" 手动跑通一次,能省下大半排查时间。
13万字C语言保姆级教程(深入):立即使用
在学习笔记中,你将探索c语言的核心概念和高级技巧!











