1. 课程导入
JTAG,全称是 Joint Test Action Group。说白了,它最初是为了解决电路板测试问题而生的。那时候板子越来越密,芯片引脚越来越多,传统探针根本没法测。后来这个组织搞出了一套标准,也就是 IEEE 1149.1。嗯,现在它成了嵌入式调试的事实标准。
我刚开始做嵌入式时,总觉得 JTAG 就是个下载程序的接口。后来踩了几次坑才明白——JTAG 真正的价值,是让你能看见芯片内部在干什么。没有它,调试就像蒙着眼睛修电路。
1.1 JTAG接口标准
标准的 JTAG 接口需要 4 根(或 5 根)信号线。我见过不少新手上来就接错线,结果芯片死活连不上调试器。
| 信号名 | 方向 | 功能描述 |
|---|---|---|
| TCK | 输入 | 测试时钟,所有操作同步于此 |
| TMS | 输入 | 测试模式选择,控制 TAP 状态机跳转 |
| TDI | 输入 | 测试数据输入,串行移入指令或数据 |
| TDO | 输出 | 测试数据输出,串行移出响应数据 |
| TRST(可选) | 输入 | 测试复位,异步复位 TAP 控制器 |
JTAG 的物理连接其实很简单。调试器通过 TCK 提供时钟,在时钟上升沿采样 TMS 和 TDI,在时钟下降沿更新 TDO。你想想看,整个调试过程就是靠这 4 根线在串行地搬数据。
1.2 TAP控制器状态机
TAP(Test Access Port)控制器是 JTAG 的核心。它是一个 16 状态的有限状态机,所有操作都围绕它展开。
我画了一张状态机图,你对照着看会清楚很多。
这个状态机其实就两条路径:一条操作数据寄存器(DR),一条操作指令寄存器(IR)。每次上电后,TAP 自动进入 Test-Logic-Reset 状态。保持 TMS 为高 5 个 TCK 周期,也能回到这个状态。
核心流程:
- 通过 TMS 控制状态机进入 Shift-IR,移入指令
- 进入 Update-IR,锁存指令
- 通过 TMS 控制状态机进入 Shift-DR,移入/移出数据
- 进入 Update-DR,锁存数据
我遇到过不少同事,调试器连不上就怀疑硬件坏了。其实多半是 TAP 状态机没复位成功。我的排查习惯是:先用示波器看 TCK 有没有,再看 TMS 能不能拉到高电平保持 5 个周期。这两步能解决 80% 的连接问题。
1.3 边界扫描原理
边界扫描(Boundary Scan)是 JTAG 最核心的应用之一。它在每个芯片的 I/O 引脚和内部逻辑之间,插入了一个 边界扫描单元(BSC)。这些 BSC 串联成一条边界扫描链,通过 JTAG 接口可以独立控制每个引脚的状态。
你想想看,这意味着什么?
- 输出控制:你可以强制某个引脚输出高电平或低电平
- 输入采样:你可以读取某个引脚当前的输入电平
- 互联测试:你可以检查板级焊接是否正常,引脚之间有没有短路
边界扫描的典型测试流程是这样的:
- 通过 Shift-IR 移入 EXTEST 指令(0x00 通常是这个)
- 进入 Shift-DR,向输出引脚写入测试向量
- 进入 Update-DR,将测试向量锁存到输出引脚
- 再次进入 Shift-DR,从输入引脚读取响应
- 对比期望值和实际值,判断互联是否正常
1.4 调试接口对比
做嵌入式这些年,我接触过好几种调试接口。每种都有自己的脾气。下面这个表格是我个人的总结:
| 接口类型 | 信号线数 | 最大速率 | 调试能力 | 典型应用 |
|---|---|---|---|---|
| JTAG | 4~5 | ~50 MHz | 断点、单步、内存读写、边界扫描 | ARM、RISC-V、FPGA |
| SWD | 2 | ~50 MHz | 断点、单步、内存读写 | Cortex-M 系列 |
| cJTAG | 2 | ~20 MHz | 与 JTAG 相同 | 引脚受限的 IoT 芯片 |
| BDM | 2~4 | ~10 MHz | 有限调试 | 飞思卡尔 ColdFire |
| Nexus | 4~16 | ~200 MHz | 全功能调试 + Trace | 高端汽车电子、DSP |
这里我想重点说说 SWD(Serial Wire Debug)。它是 ARM 公司搞出来的,只有两根线:SWDIO(数据)和 SWCLK(时钟)。说白了,就是把 JTAG 的 TMS 和 TDI 合并了。
我个人的选择原则很简单:
- Cortex-M 系列:优先用 SWD,省引脚,速率不输 JTAG
- ARM9/Cortex-A 系列:必须用 JTAG,因为需要边界扫描和更复杂的调试功能
- FPGA:只能用 JTAG,因为要兼顾配置和调试
- 引脚极度受限:考虑 cJTAG,但要注意调试器兼容性
最后说一句,JTAG 虽然看起来老,但它依然是嵌入式调试的基石。后面的章节我们会深入 Trace 流分析,你会发现,所有高级调试手段,底层都离不开 JTAG 这套机制。