---
title: 调试与编程接口
url: https://doc.liz6.com/hardware/10-practices-and-tools/03-debug-and-programming-interfaces
locale: zh
area: hardware
tags:
- hardware
- 实践与工具
date: 2026-06-30
modified: 2026-07-16
description: JTAG/SWD 是从外面接管 CPU 的口子(断点、单步、烧录、边界扫描),DFU 和 UART bootloader 是芯片自带的刷机通道。开发用 SWD,量产先烧 bootloader 再批量 DFU,现场升级走 OTA——不同阶段用不同的口。
---

# 调试与编程接口

> 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**——它把三方翻译到一起：

```mermaid
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["目标芯片"]
```

```bash
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 的固件要等几十秒。

### 三种通道在产品生命周期里各就各位

```mermaid
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 传感器无响应为例）：

```mermaid
flowchart TD
    S["I2C 传感器不工作"] --> C["抓 SDA/SCL 波形"]
    C --> Q{"地址后有 ACK 吗?"}
    Q -->|无 ACK| A["地址错 / 接线错 / 芯片没上电"]
    Q -->|有 ACK| B{"寄存器读写值对吗?"}
    B -->|不对| D["读手册核对寄存器时序"]
    B -->|对| E["问题不在总线 → 回固件逻辑找"]
```

SPI Flash 不稳定同理：抓 CS 时序、CLK 频率、数据完整性，先把物理层排除掉。总线协议本身的细节见[串行总线](/hardware/06-interfaces-and-communication/02-serial-bus-protocols.md)。

## 选型速查

| 芯片/场景 | 推荐 |
|---|---|
| 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, 边界扫描, 逻辑分析仪*
