本页目录
调试与编程接口
JTAG/SWD 是从外面接管 CPU 的口子(断点、单步、烧录、边界扫描),DFU 和 UART bootloader 是芯片自带的刷机通道。开发用 SWD,量产先烧 bootloader 再批量 DFU,现场升级走 OTA——不同阶段用不同的口。
概述
围绕一颗 MCU 的"接口"其实在干三件不同的事:调试(暂停 CPU、断点单步、读写内存)、烧录(把固件写进 Flash)、产测(不跑固件验证焊接)。理解各接口,先分清它属于哪一类、依赖什么前提:
| 接口 | 线数 | 能做什么 | 前提 |
|---|---|---|---|
| JTAG | 4~5 | 调试 + 烧录 + 边界扫描 | 外接调试器 |
| SWD | 2 | 调试 + 烧录(ARM Cortex) | 外接调试器 |
| UART bootloader | 2 | 只能烧录 | 芯片 Boot ROM 内置 |
| USB DFU | 1 根 USB 线 | 只能烧录 | 芯片 Boot ROM 内置 |
| ISP/ICSP | 6 pin | 烧录(AVR 系) | 编程器 |
关键区别:JTAG/SWD 是从外面接管 CPU——芯片死活都能救、能调试;DFU/UART bootloader 是芯片自己配合刷机——不需要专用硬件,但固件把 boot 引脚配置搞坏就进不去了。
JTAG (IEEE 1149.1)
上世纪 80 年代为测试 PCB 焊接而生(Joint Test Action Group),后来才捎带成了调试标准。
| 引脚 | 全称 | 作用 |
|---|---|---|
| TMS | Test Mode Select | 驱动内部状态机 |
| TCK | Test Clock | 时钟 |
| TDI | Test Data In | 数据入 |
| TDO | Test Data Out | 数据出 |
| TRST | Test Reset | 可选复位 |
多芯片可以菊花链串联(TDI → TDO → 下一颗的 TDI),一个调试口管整板。电压需匹配目标(1.8V~5V),速度典型 1~50MHz。
它的三种用途里,边界扫描最能体现出身:JTAG 可以直接控制/读取芯片每个引脚的电平,不运行任何固件就能验证 PCB 上两颗芯片之间的连线是否焊通——这是产线测试的基石。调试(暂停 CPU、断点、读写内存/Flash)和烧录反而是后来附加的能力。
SWD (Serial Wire Debug)
ARM 给 Cortex 设计的精简替代:把 JTAG 的 4~5 根线压到 2 根——SWDIO(双向数据)+ SWCLK(时钟),外加必须的 GND。调试能力不缩水:断点/单步/寄存器访问、Flash 编程、经 DP/AP 机制的多核调试,速度可达 50MHz+(CoreSight)。
| JTAG | SWD | |
|---|---|---|
| 线数 | 4~5 | 2 |
| 功能 | 全量 + 边界扫描 + 菊花链 | 调试 + 烧录,够用 |
| 覆盖 | 几乎所有芯片(含 FPGA/DSP) | ARM Cortex 系列 |
| PCB 占用 | 多 | 少,两根线随便引 |
选择逻辑很直接:Cortex-M 开发一律 SWD;非 ARM、复杂 SoC、要边界扫描 → JTAG;拿不准就把 JTAG 口留全(JTAG 引脚可复用出 SWD)。
调试器硬件与 OpenOCD
| 调试器 | 接口 | 价格 | 定位 |
|---|---|---|---|
| ST-Link V2 | SWD | $2~10 (clone) | 学 STM32 的第一选择 |
| DAP-Link (CMSIS-DAP) | SWD+JTAG | $5~15 | 开源、通用 ARM |
| J-Link (SEGGER) | SWD+JTAG | $20~1000 | 专业:速度快、RTT、无限断点 |
| FT2232H | JTAG | $10~20 | 配 OpenOCD 的万金油 |
| Raspberry Pi Pico | SWD | $4 | 刷 picoprobe 即变调试器 |
软件侧的枢纽是 OpenOCD——它把三方翻译到一起:
flowchart LR
GDB["gdb-multiarch<br>(断点/单步/变量)"] <-->|"GDB remote 协议<br>:3333"| O["OpenOCD"]
O <-->|USB| P["调试器<br>ST-Link / J-Link / DAP"]
P <-->|SWD / JTAG| T["目标芯片"]
()
接口侧支持 ST-Link/J-Link/DAP-Link/FTDI 等,目标侧覆盖几乎所有 ARM + RISC-V + MIPS——开源生态里它就是事实标准。
芯片自带的刷机通道
USB DFU
芯片的 Boot ROM(出厂固化,刷不掉)检测特定条件后,让芯片作为 USB 设备枚举,Host 直接经 USB 送固件:
- STM32: BOOT0 拉高上电 → System Memory bootloader
- nRF52: 特定寄存器值 + 复位
- RP2040: 按住 BOOTSEL 上电 → 直接显示为 U 盘,固件拖进去就刷(体验最好的 DFU)
优势是零额外硬件——用户手里只要有根 USB 线就能刷机;劣势是只能烧录,不能调试。
UART Bootloader
同样是 Boot ROM 行为,媒介换成串口(XMODEM/YMODEM/自定义协议):
- STM32: System bootloader 听 USART1
- ESP32: ROM bootloader,esptool 自动进入(或 GPIO0 拉低)
- AVR: 出厂没有,要先用 ISP 烧一个(Arduino bootloader 就是它)
- MSP430: BSL
只要有串口就能刷,代价是慢——115200bps 约 10KB/s,几百 KB 的固件要等几十秒。
三种通道在产品生命周期里各就各位
flowchart LR
DEV["开发期<br>SWD/JTAG<br>调试 + 随时烧录"] --> FAC["产线<br>先 SWD 烧 bootloader<br>再 DFU 批量灌固件"]
FAC --> FIELD["现场<br>APP 内置 DFU/OTA<br>用户自助升级"]
逻辑分析仪:总线级调试
调试器解决"代码哪里错了",逻辑分析仪解决"线上到底发生了什么"——固件看起来对但外设不理你时,用它一锤定音。Saleae / DSLogic / PulseView 都内置协议解码器:I2C(自动解码地址+数据+ACK)、SPI(逐帧显示)、UART(按波特率转 ASCII)、CAN/LIN、1-Wire;还支持协议级触发(如"I2C 上出现地址 0x68 时开始抓")。
典型排障(以 I2C 传感器无响应为例):
flowchart TD
S["I2C 传感器不工作"] --> C["抓 SDA/SCL 波形"]
C --> Q{"地址后有 ACK 吗?"}
Q -->|无 ACK| A["地址错 / 接线错 / 芯片没上电"]
Q -->|有 ACK| B{"寄存器读写值对吗?"}
B -->|不对| D["读手册核对寄存器时序"]
B -->|对| E["问题不在总线 → 回固件逻辑找"]
SPI Flash 不稳定同理:抓 CS 时序、CLK 频率、数据完整性,先把物理层排除掉。总线协议本身的细节见串行总线。
选型速查
| 芯片/场景 | 推荐 |
|---|---|
| STM32 开发 | SWD (ST-Link) |
| nRF52 开发 | SWD (J-Link / DAP-Link) |
| ESP32 开发 | 串口(内置 bootloader,esptool) |
| RP2040 开发 | SWD 或 USB 拖放 |
| AVR (Arduino) | ISP (6-pin) |
| ARM Linux 内核调试 | JTAG (OpenOCD + GDB) |
| FPGA | JTAG (Vivado/Quartus 自带) |
| 现场固件升级 | DFU / OTA |
| 传感器/外设不响应 | 逻辑分析仪抓总线 |
| 产线测试 | JTAG 边界扫描 |
参考
- JTAG: IEEE 1149.1 · ARM Debug Interface (ADIv5) 手册
- OpenOCD: openocd.org/doc
- SEGGER: wiki.segger.com (RTT/J-Link 文档质量极高)
- Sigrok/PulseView: sigrok.org (开源逻辑分析)
关键词: JTAG, SWD, SWDIO, SWCLK, OpenOCD, DFU, Boot ROM, bootloader, ST-Link, J-Link, DAP-Link, 边界扫描, 逻辑分析仪