2. JTAG 与 SWD 接口详解
调试接口,说白了就是调试器和芯片之间的“通信管道”。ARMv8 内核最常用的两种接口,就是 JTAG 和 SWD。JTAG 是个老牌标准,SWD 是 ARM 后来推出的精简版。很多工程师刚接触时容易混淆,我当年也踩过坑——拿着 JTAG 的线序去接 SWD,结果死活连不上。
这一节,咱们就把这两个接口彻底讲透。
2.1 JTAG 信号定义与链式扫描
JTAG(Joint Test Action Group)最初是为了电路板测试而生的,后来被 ARM 拿来做调试接口。它至少需要 4 根信号线,加上可选的第 5 根,一共 5 根。
| 信号名 | 方向 | 功能描述 |
|---|---|---|
| TCK | 调试器 → 芯片 | 时钟信号,所有操作同步于此 |
| TMS | 调试器 → 芯片 | 模式选择,控制 TAP 状态机跳转 |
| TDI | 调试器 → 芯片 | 数据输入,串行送入指令或数据 |
| TDO | 芯片 → 调试器 | 数据输出,串行读出响应 |
| nTRST | 调试器 → 芯片 | (可选)TAP 复位,低电平有效 |
JTAG 的核心机制是 TAP 状态机。调试器通过 TMS 信号在 TCK 的上升沿驱动状态跳转,完成“指令扫描”或“数据扫描”。
链式扫描(Daisy Chain):当多个 JTAG 设备串联时,TDO 接下一个的 TDI,形成一条扫描链。调试器通过一条链就能访问所有设备。我在调试多核 ARMv8 芯片时,经常用链式扫描同时挂起所有核心,效率很高。
链式扫描的典型流程:
- 调试器通过 TMS 驱动状态机进入 Shift-IR 状态,送入指令码。
- 切换到 Shift-DR 状态,送入或读出数据。
- 每个设备在链中占据固定长度的寄存器位,调试器需要知道链上所有设备的 ID 和寄存器长度。
- 扫描完成后,回到 Run-Test/Idle 状态,等待下一次操作。
注意:链式扫描时,如果某个设备的 TAP 状态机跑飞了,整条链都会卡死。我曾经遇到过一颗芯片的 nTRST 引脚虚焊,导致链上所有设备都无法正常扫描。排查了整整一天,最后用示波器量 nTRST 电平才发现问题。
2.2 SWD 双线协议
SWD(Serial Wire Debug)是 ARM 在 Cortex-M 时代推出的精简接口,后来 ARMv8 也全面支持。它只用了两根线:SWDIO(双向数据线)和 SWCLK(时钟线)。
你想想看,JTAG 至少 4 根线,SWD 只要 2 根。对于引脚紧张的芯片,SWD 简直是救星。我做过一个 IoT 项目,芯片封装只有 8 个引脚,硬是挤出了 SWD 接口,省掉了 JTAG 的 TDI 和 TDO。
SWD 协议的核心是 数据包(Packet) 结构:
| 字段 | 长度 | 说明 |
|---|---|---|
| 起始位 | 1 bit | 固定为 0 |
| AP/DP 选择 | 1 bit | 0 = DP(调试端口),1 = AP(访问端口) |
| 读写标志 | 1 bit | 0 = 写,1 = 读 |
| 寄存器地址 | 2 bits | 选择 DP/AP 内部的寄存器 |
| 奇偶校验 | 1 bit | 对前 5 bits 做偶校验 |
| 停止位 | 1 bit | 固定为 0 |
| Park 位 | 1 bit | 固定为 1 |
SWD 的读写操作是半双工的。调试器发送请求包后,芯片在下一个 SWCLK 周期返回响应包。响应包包含 ACK(应答)、数据(读操作时)和奇偶校验位。
个人经验:SWD 的时钟频率可以很高,但实际调试时我习惯先降到 1 MHz 以下,确认连接稳定后再逐步提高。有些廉价的调试线在高速下容易丢包,表现为“连接断开”或“校验错误”。
2.3 JTAG 与 SWD 的切换机制
ARMv8 芯片通常同时支持 JTAG 和 SWD。但芯片上电后默认处于哪种模式?答案是 JTAG 模式。为什么?因为 JTAG 是 IEEE 标准,兼容性更好。
切换机制其实很简单:调试器通过 JTAG 的 TMS 和 TCK 发送一串特定的序列,芯片检测到后就会切换到 SWD 模式。这个序列叫做 SWJ-DP 切换序列(SWJ-DP Switch Sequence)。
具体流程如下:
- 调试器在 TCK 上输出 50 个以上的时钟周期,同时 TMS 保持高电平。这会让 JTAG TAP 状态机进入 Test-Logic-Reset 状态。
- 然后发送 16 位的切换序列:
0xE79E(二进制:1110 0111 1001 1110)。 - 芯片检测到序列后,内部从 JTAG 逻辑切换到 SWD 逻辑。
- 之后,SWCLK 和 SWDIO 开始按 SWD 协议通信。
关键点:切换序列必须在 TCK 的上升沿采样,且 TMS 的时序必须严格对齐。我见过不少工程师用逻辑分析仪抓波形,发现 TMS 的建立时间不够,导致切换失败。嗯,这里要注意:切换完成后,JTAG 的 TDI 和 TDO 引脚可以复用为 GPIO 或其他功能。
下面这张图展示了 JTAG 和 SWD 的切换流程:
切换完成后,调试器可以通过 SWD 协议访问 DP(Debug Port)和 AP(Access Port)。DP 负责控制调试逻辑,AP 负责访问系统总线(如 AXI、AHB)。
避坑指南:我曾经在一个项目里,芯片的 SWD 接口死活切不过去。查了半天,发现是 PCB 上 SWCLK 和 SWDIO 的走线太长,导致信号反射。后来在调试器端加了 22Ω 的串联电阻,问题就解决了。所以,如果你遇到切换失败,先检查信号质量。
2.4 JTAG 与 SWD 的对比
| 特性 | JTAG | SWD |
|---|---|---|
| 信号线数量 | 4~5 根 | 2 根 |
| 通信方式 | 全双工 | 半双工 |
| 链式扫描 | 原生支持 | 不支持 |
| 最大时钟频率 | 通常 ≤ 50 MHz | 通常 ≤ 50 MHz |
| 引脚复用 | TDI/TDO 可复用 | SWDIO 可复用 |
| 调试速度 | 较快(全双工) | 略慢(半双工) |
| 适用场景 | 多核、多设备链式调试 | 引脚受限、单核调试 |
我个人习惯:如果芯片引脚够用,优先用 JTAG,因为全双工在批量读写内存时更快。但如果引脚紧张,或者只需要调试一个核心,SWD 完全够用,而且布线简单。
小技巧:很多调试器(如 J-Link、ST-Link)都支持自动检测接口类型。你插上 SWD 线,它会先尝试 JTAG 连接,失败后自动发送切换序列。但我不建议完全依赖自动检测——手动指定接口类型更可靠,尤其是在调试刚上电的芯片时。