Black Magic Probe 教程:30 块把 BluePill 变成免 OpenOCD 的 ARM 调试器
嵌入式调试 Cortex-M 的链路,绝大多数人已经默认了它的繁琐:IDE 先起 OpenOCD,OpenOCD 再拉一个调试器驱动(ST-Link / J-Link / CMSIS-DAP),驱动最后才通过 SWD/JTAG 摸到芯片。中间只要 .cfg 写错一个参数、Python 环境缺一个依赖,GDB 就对着一个连不上的端口报 timeout。
我折腾过很多次"为什么连不上",翻 .cfg 翻十分钟,最后发现是 transport select swd 抄成了 transport select jtag。
问题的根子在架构:调试器在物理层要做的其实只有一件事——把 SWD/JTAG 协议翻译成 GDB 能读懂的 RSP(Remote Serial Protocol)。这个翻译工作,凭什么一定要放在 PC 上、再套一层 OpenOCD 中间件?
Black Magic Probe(BMP)给的答案是:把翻译直接搬进调试器自己的芯片里。
BMP 是什么
一个完全开源(硬件 + 固件)的 ARM Cortex-M 调试器。它最反直觉的一点:GDB Server 直接跑在调试器板上的 STM32 芯片里,而不是跑在你的电脑上。
USB 插上电脑,操作系统看到的不是"ST-Link Debugger",而是一个 CDC 虚拟串口 /dev/ttyACM0。你的 GDB 直接连这个串口:
$ arm-none-eabi-gdb
(gdb) target extended-remote /dev/ttyACM0 # 直连调试器,它就是 GDB Server
(gdb) monitor swdp_scan # 自动扫 SWD 总线上的设备
(gdb) attach 1 # 连接第一个目标
(gdb) load firmware.elf # 烧写
(gdb) continue # 跑起来
没有 OpenOCD、没有 pyOCD、没有 JLinkGDBServer、没有配置文件。
更关键的是成本:你不需要买官方硬件。一块 BluePill(STM32F103C8T6 最小系统板)刷一个固件,它就变成了 BMP,总投入不到 30 块。
30 块自制一个
物料清单:
- BluePill 开发板(STM32F103C8T6,淘宝搜"BluePill 最小系统",¥15-25)
- USB-TTL 串口模块(CP2102 或 CH340,¥5-10)
- 4 根杜邦线
烧写是一次性动作,走官方预编译固件:
# 1. 下载预编译固件
wget https://github.com/blackmagic-debug/blackmagic/releases/download/v2.0.0-rc2/blackmagic_allinone-bluepill.bin
# 2. BluePill 进入系统存储器 boot 模式
# 按住 BOOT0 → 按一下 NRST → 松开 BOOT0
# 3. 用 stm32flash 烧写
stm32flash -w blackmagic_allinone-bluepill.bin -v /dev/ttyUSB0
# 4. 拔掉 USB-TTL,用 Micro-USB 连接 BluePill 到电脑
# 系统会出现两个虚拟串口:
# - /dev/ttyACM0 → GDB Server
# - /dev/ttyACM1 → 虚拟串口(UART 透传,接目标板调试串口)
烧完后接线到目标板:
| BMP 引脚(BluePill) | 目标板引脚 | 说明 |
|---|---|---|
| PB14 | SWDIO | 数据线 |
| PA5 | SWCLK | 时钟线 |
| GND | GND | 共地 |
| PB7(可选) | TX | 目标板 printf 透传到 /dev/ttyACM1 |
四根线。不用接复位线——BMP 通过 SWD 的 SRST 命令复位目标芯片。
为什么"内置 GDB Server"是杀招
所有调试器在底层做的是同一件事:SWD/JTAG ↔ GDB RSP 的协议转换。区别只在转换发生在哪一层:
| 方案 | 转换在哪里 | 需要的中间件 |
|---|---|---|
| ST-Link + OpenOCD | PC 上 | OpenOCD + 配置 + 驱动 |
| J-Link + JLinkGDBServer | PC 上 | Segger 闭源软件 |
| CMSIS-DAP + pyOCD | PC 上 | pyOCD + Python 环境 |
| Black Magic Probe | 调试器芯片上 | 无 |
BMP 把 SWD 协议解析和 GDB RSP 序列化全部压在 STM32F103 上做完。PC 端只要一个标准的 arm-none-eabi-gdb,不需要装驱动、不需要 .cfg、不需要 Python。
这个差异在 CI/CD 场景会被放大。自动化测试跑在 Docker 容器里,你只需要 gdb-multiarch,不必为了一个调试步骤去装 OpenOCD + 一堆依赖 + 维护配置文件。BMP 插上,容器里 /dev/ttyACM0 出现,GDB 直连,脚本照跑。
还有一个小优化:GDB noackmode(BMP 默认开启)。正常 GDB 与 GDB Server 之间每个数据包都要 ACK 确认;BMP 默认关掉 ACK,理由是 USB 底层可靠性已经足够,ACK 纯属冗余。在高速单步调试时,这一改能把响应延迟从约 5ms 压到约 2ms。
顺带送的:SWO、RTT、多架构
SWO 追踪直接解析。 J-Link 和 ST-Link 都能收 SWO(Serial Wire Output,目标芯片通过一根额外引脚以 1-30MHz 往外吐 PC 采样、事件、ITM printf),但多数调试器只把原始 bitstream 转发给 PC,让 PC 端软件去解析。BMP 在调试器芯片上直接解 SWO 帧——把目标板 SWO 接到 BMP 的一个 GPIO,GDB 里 monitor swo start,printf 直接出现在 GDB 控制台,不需要 PC 端工具。
RTT(Real-Time Transfer)。 SEGGER 发明的协议:目标芯片在 RAM 里建环形缓冲区,调试器经 SWD 读这个缓冲区拿 printf 输出,比 SWO 慢但省一根引脚。BMP 新版本支持 RTT,monitor rtt 一行开启。
多架构。 不只 Cortex-M。BMP 还支持 Cortex-A(树莓派 2/3 的 bare-metal 调试)、RISC-V(SiFive E31/E51 走 JTAG)、STM8(走 SWIM)。注意 BluePill 版的 BMP 因为 STM32F103 只有一个 SWD 外设,只能做 ARM Cortex-M;要 JTAG + SWD 双支持得用 STM32F407(BlackPill)版。
常用命令速查:
(gdb) target extended-remote /dev/ttyACM0 # 连接 BMP
(gdb) monitor swdp_scan # 扫描 SWD 总线
Available Targets:
No. Att Driver
1 STM32F4xx
(gdb) attach 1 # 连接目标 1
(gdb) monitor option erase_mass # Flash 全擦
(gdb) load firmware.elf # 烧写
(gdb) monitor rtt # 开启 RTT(固件启用时)
(gdb) monitor swo start # 开启 SWO 追踪
(gdb) continue # 运行
局限说清楚(踩坑清单)
官方仓库已归档。 2026 年 3 月 blackmagic-debug/blackmagic 在 GitHub 设为只读,不再有官方更新。社区 fork compuphase/blackmagic-firmware 仍在维护;对绝大多数 Cortex-M 调试场景,v2.0.0-rc2 的功能已经够用——嵌入式调试器的功能演进本来就很慢。
BluePill 版只支持 Cortex-M。 STM32F103 只有一个 SWD 外设,做不了 JTAG。需要 Cortex-A / RISC-V / ETM 指令追踪,得上 STM32F407 版或直接 J-Link。
SWD 时钟上限约 2MHz。 对照:ST-Link v2 是 4MHz,J-Link 能到 50MHz。日常设断点、看变量、单步执行 2MHz 绰绰有余;但烧大固件(比如 512KB)会比 ST-Link 慢一半左右。v2.0.0-rc2 把默认 SWD 时钟从 1.8MHz 提到了 2.0MHz,再高 F103 的 GPIO 翻转速度跟不上。
没有 IDE 集成。 Segger 有 Ozone、ST 有 CubeIDE 内置调试、Keil 有 µVision。BMP 的交互面是 GDB 命令行(或 VS Code 的 Cortex-Debug 插件)。习惯 IDE 一键调试的人,得习惯在 gdb 里手敲 monitor 命令。
淘宝 BluePill 质量参差。 ¥15 的 BluePill 大概率不是正品 STM32F103,而是 GD32F103 或 CS32F103 克隆片,USB 外设行为有细微差异。刷完固件电脑不认 USB 设备,多半是克隆片 USB D+ 上拉时序不对。建议买 ¥25 以上的"原装 STM32"版,或直接用 WeAct BlackPill v2.0(STM32F401CCU6,¥35),USB 更稳、性能更好。
总结
OpenOCD 不会消失,J-Link 也依然是最好的商业调试器。但如果你烦透了配置和中间件,花 30 块买块 BluePill 刷个固件,就能体验 GDB 直连的清爽。当你在终端敲下 target extended-remote /dev/ttyACM0、看到 Remote debugging using /dev/ttyACM0 的那一刻,大概率不会再想回去写 .cfg 了。
- 归档仓库:github.com/blackmagic-debug/blackmagic
- 社区维护分支:codeberg.org/compuphase/blackmagic-firmware
- 官方文档:black-magic.org
浙公网安备 33010602011771号