本页目录

调试与编程接口

JTAG/SWD 是从外面接管 CPU 的口子(断点、单步、烧录、边界扫描),DFU 和 UART bootloader 是芯片自带的刷机通道。开发用 SWD,量产先烧 bootloader 再批量 DFU,现场升级走 OTA——不同阶段用不同的口。

概述

围绕一颗 MCU 的"接口"其实在干三件不同的事:⁠调试⁠(暂停 CPU、断点单步、读写内存)、⁠烧录⁠(把固件写进 Flash)、⁠产测⁠(不跑固件验证焊接)。理解各接口,先分清它属于哪一类、依赖什么前提:

接口线数能做什么前提
JTAG4~5调试 + 烧录 + 边界扫描外接调试器
SWD2调试 + 烧录(ARM Cortex)外接调试器
UART bootloader2只能烧录芯片 Boot ROM 内置
USB DFU1 根 USB 线只能烧录芯片 Boot ROM 内置
ISP/ICSP6 pin烧录(AVR 系)编程器

关键区别:JTAG/SWD 是从外面接管 CPU——芯片死活都能救、能调试;DFU/UART bootloader 是芯片自己配合刷机⁠——不需要专用硬件,但固件把 boot 引脚配置搞坏就进不去了。

JTAG (IEEE 1149.1)

上世纪 80 年代为测试 PCB 焊接而生(Joint Test Action Group),后来才捎带成了调试标准。

引脚全称作用
TMSTest Mode Select驱动内部状态机
TCKTest Clock时钟
TDITest Data In数据入
TDOTest Data Out数据出
TRSTTest 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)。

JTAGSWD
线数4~52
功能全量 + 边界扫描 + 菊花链调试 + 烧录,够用
覆盖几乎所有芯片(含 FPGA/DSP)ARM Cortex 系列
PCB 占用少,两根线随便引

选择逻辑很直接:Cortex-M 开发一律 SWD;非 ARM、复杂 SoC、要边界扫描 → JTAG;拿不准就把 JTAG 口留全(JTAG 引脚可复用出 SWD)。

调试器硬件与 OpenOCD

调试器接口价格定位
ST-Link V2SWD$2~10 (clone)学 STM32 的第一选择
DAP-Link (CMSIS-DAP)SWD+JTAG$5~15开源、通用 ARM
J-Link (SEGGER)SWD+JTAG$20~1000专业:速度快、RTT、无限断点
FT2232HJTAG$10~20配 OpenOCD 的万金油
Raspberry Pi PicoSWD$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["目标芯片"]
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg   # 起 GDB server
gdb-multiarch firmware.elf
(gdb) target remote :3333

接口侧支持 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)
FPGAJTAG (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, 边界扫描, 逻辑分析仪