无硬件调试STM32:VSCode+Renode实战
实战背景
在传统的嵌入式开发中,调试代码通常需要经历:连接开发板 → 编译烧录 → 等待复位 → 设置断点 → 运行。每次改动一行代码都意味着重复这一整套流程,大幅拖慢了迭代速度。更棘手的是,硬件并不总是随手可得——出差在外、USB 端口紧缺、开发板被同事借用,甚至因硬件故障而阻塞整个调试过程。
Renode 是由 Antmicro 开发的开源硬件仿真平台,能够完整模拟 Cortex-M 系列微控制器(包括 CPU、内存及多种外设),并且内置了 GDB Server。配合 VS Code 的 Cortex-Debug 扩展,开发者无需实物开发板即可在仿真环境中进行断点设置、单步执行、变量查看等所有常规调试操作。
本文以 STM32F407 搭配 CubeMX 生成项目和 CMake 构建系统为例,记录从零搭建这一无硬件调试环境的完整过程。
环境准备
组件列表:
-
Renode:硬件仿真器,github.com/renode/renode 下载
-
VS Code 扩展:搜索安装 Cortex-Debug(作者 marus25)
-
arm-none-eabi-gdb:调试客户端,CubeMX 工具链自带
-
固件 ELF 文件:编译产物,必须带 Debug 符号(-g 编译)
STM32F407 仿真脚本(.resc)
第一步:Renode 启动脚本
创建一个 .resc 脚本,创建机器、加载芯片平台描述、启动 GDB Server、加载固件、启动串口:
:name: STM32F407VGT6 Discovery
:description: Test script for 4WD_PTZ firmware on STM32F4 Discoveryusing sysbus
mach create "STM32F407"
machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.replcpu PerformanceInMips 125
#加载测试固件
sysbus LoadELF @myProjectTest/binaries/debug/renode_test.elf#打开串口1
showAnalyzer sysbus.usart1#打开GDB服务(端口3333)
machine StartGdbServer 3333 truestart
VS Code配置文件
在项目根目录 .vscode/ 下创建两个文件。
launch.json — 调试启动配置
按 F5 时 VS Code 读到它,知道:用 Cortex-Debug 扩展,开 arm-none-eabi-gdb,连 localhost:3333(Renode 的 GDB Server),加载 renode_test.elf,程序自动停在 main()。连之前先编译一次(preLaunchTask)。
一句话:怎么连上 Renode 开始调试。
{
"version": "0.2.0",
"configurations": [
{
"name": "Renode GDB Debug",
"type": "cortex-debug",
"request": "attach",
"servertype": "external",
"gdbPath": "${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-gdb",
// 🔄 换成目标芯片型号
"device": "STM32F407",
// 🔄 换成新固件的 ELF 文件路径
"executable": "${workspaceFolder}/build/Debug/renode_test.elf",
// 🔄 Renode GDB 端口,如果换了端口号改这里
"gdbTarget": "localhost:3333",
"runToEntryPoint": "main",
// 🔄 必须与 tasks.json 中 Build 任务的 label 一致
"preLaunchTask": "Build (CMake Debug)",
"preAttachCommands": [
"set remotetimeout 30",
"set print pretty on",
"set print array on",
"set print array-indexes on"
]
}
]
}
tasks.json — 构建任务
Ctrl+Shift+B 触发 Build 任务:跑 cmake --build --preset Debug,编译输出里的错误/警告会自动解析成可点击跳转的列表。另外提供 Clean(清构建产物)和 Rebuild(清完重编)。
一句话:不用离开编辑器就能编译、清空、重编。
{
"version": "2.0.0",
"tasks": [
{
// 🔄 改了这个 label,launch.json 的 preLaunchTask 也要同步改
"label": "Build (CMake Debug)",
"type": "shell",
"command": "cube-cmake",
"args": [
"--build",
"--preset",
// 🔄 换成 CMakePresets.json 里对应的 preset 名称
"Debug"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*):([0-9]+):([0-9]+):[0-9]*:\\s*(warning|error|fatal error):\\s*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
"presentation": {
"reveal": "silent",
"panel": "shared"
}
},
{
"label": "Clean",
"type": "shell",
"command": "cube-cmake",
"args": [
"--build",
"--preset",
"Debug",
"--target",
"clean"
],
"group": {
"kind": "build"
},
"presentation": {
"reveal": "always",
"panel": "shared"
}
},
{
"label": "Rebuild",
// 🔄 dependsOn 里的名字必须和上面两个任务的 label 完全一致
"dependsOn": [
"Clean",
"Build (CMake Debug)"
],
"dependsOrder": "sequence",
"group": {
"kind": "build"
},
"presentation": {
"reveal": "always",
"panel": "shared"
}
}
]
}
启动仿真
固件源码
本文固件仅测试GDB服务器是否接通,所以源码比较简单。
/* 发送一条欢迎消息 */
char *msg = "UART1 Test Started!\r\n";
HAL_USART_Transmit(&husart1, (uint8_t *)msg, strlen(msg), 1000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* 每隔 1 秒发送一次数据 */
char *ping = "Hello from STM32F407 UART1!\r\n";
HAL_USART_Transmit(&husart1, (uint8_t *)ping, strlen(ping), 1000);
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
运行.resc脚本
运行脚本以后先暂停仿真,本次固件只是测试使用。

VS Code开启调试
测试成功,可以进行单步调试等。

总结
本文介绍了一套完全脱离硬件开发板的嵌入式调试方案,使用 VS Code 搭配 Renode 硬件仿真器与 arm-none-eabi-gdb,在电脑上即可对 STM32 进行断点、单步、变量查看等操作。
核心工具包括:
-
Renode:模拟 Cortex-M 芯片的完整硬件环境,并内置 GDB Server。
-
VS Code 扩展 Cortex-Debug:提供图形化调试前端。
-
arm-none-eabi-gdb:作为调试客户端连接 Renode。
配置过程分为三步:
-
编写 Renode 启动脚本,加载芯片描述文件、开启 GDB Server(端口 3333)、加载固件 ELF,并启动仿真。
-
在 VS Code 中配置 launch.json(指定 GDB 路径、设备型号、可执行文件、连接目标等)与 tasks.json(构建任务),实现按 F5 自动编译并连接调试器。
-
终端运行 Renode 脚本后,在 VS Code 中按 F5 启动调试,CPU 会自动停在 main 函数,随后可像普通软件调试一样操作。
额外能力包括通过 SVD 文件查看外设寄存器,以及通过 GDB 命令美化变量显示。
与传统硬件调试相比,该方案无需开发板、无烧录等待、外设状态可见、连接稳定,极大提升了逻辑调试和早期驱动开发的效率。但对复杂外设行为、精细时序模拟等场景,仍需回归真实硬件。整体配置可快速迁移至其他 Cortex-M 芯片,只需调整芯片型号和平台描述文件。
更多推荐



所有评论(0)