2. JTAG协议基础

JTAG(Joint Test Action Group)接口在电气上只有四根(有时五根)关键信号:TCK、TMS、TDI、TDO,以及可选的TRST。真正让这四根线具备"寻址任意芯片内部寄存器"能力的,是IEEE 1149.1标准定义的TAP控制器状态机。理解JTAG,本质上就是理解"TMS如何驱动状态迁移、IR如何选中某个寄存器、DR如何承载数据"这三件事的配合关系。

TAP状态机:用TMS串行决定迁移路径

TAP(Test Access Port)控制器是一个16状态的有限状态机,所有状态迁移只由TMS在TCK上升沿的采样值决定。TMS为1时走"上支路",TMS为0时走"下支路",两条支路在若干状态处汇合。核心状态包括:

  • Test-Logic-Reset(TLR):上电或TMS连续保持5个TCK高电平后进入,此时IR被强制加载全1(即BYPASS指令),芯片处于安全复位态。
  • Run-Test/Idle:空闲态,测试逻辑可在此执行自测,也是进入DR/IR扫描的起点。
  • Select-DR-Scan / Select-IR-Scan:分叉点,决定本次扫描操作的是数据寄存器还是指令寄存器。
  • Capture-DR / Shift-DR / Update-DR:DR扫描的三段式——捕获当前值、移位输入输出、更新生效。
  • Capture-IR / Shift-IR / Update-IR:IR扫描的三段式,结构完全对称。

关键点在于:Shift-DR和Shift-IR是唯一允许TDI→TDO串行移位的状态。每来一个TCK,TDI上的1位数据进入移位寄存器最低位,最高位从TDO移出。因此一次N位移位需要N个TCK周期,且移位期间TMS必须保持0。若中途TMS拉高,状态机将离开Shift态,移位被截断。

指令寄存器与数据寄存器

IR(Instruction Register)是一个移位寄存器,其宽度由芯片决定(常见4位、5位、8位)。通过Shift-IR移入一条指令码,Update-IR后该指令生效,选中对应的数据寄存器。例如ARM CoreSight DAP中,IR宽度为4位,指令0x0对应IDCODE,0x1对应ABORT,0xA对应DPACC,0xB对应APACC。这些指令码是芯片设计时固定的,必须查阅对应TRM。

DR(Data Register)是一组可选中的寄存器,常见类型包括:

  • BYPASS:1位,用于旁路该芯片,缩短扫描链。
  • IDCODE:32位,包含厂商ID、部件号和版本,是识别芯片的第一手信息。
  • BSR(Boundary Scan Register):边界扫描寄存器,位数等于芯片引脚数,用于板级互连测试。
  • 专用调试寄存器:如CoreSight的DP/AP寄存器,用于访问调试总线。

IR选中的是哪条DR,决定了后续Shift-DR移入移出的数据被解释成什么。这就是"先写IR、再读写DR"这一JTAG操作范式的由来。

边界扫描链与多器件级联

边界扫描链(Boundary Scan Chain)是JTAG用于板级测试的核心机制。每个I/O引脚旁有一个边界扫描单元(BCell),所有BCell串联成BSR。在EXTEST指令下,BSR可以驱动/采样引脚电平,从而检测PCB走线是否开路、短路。BSR的位数等于参与扫描的引脚数,扫描一次需要对应数量的TCK。

当板上有多个JTAG器件时,它们的TDI/TDO首尾相连形成菊花链(Daisy Chain):前一级TDO接后一级TDI,最后一级TDO回到调试器。此时所有器件的IR和DR在逻辑上串联,调试器必须知道每个器件在链中的位置和IR宽度,才能正确寻址。例如链上有三个器件,IR宽度分别为4、5、4,则一次IR扫描需要移入13位,其中前4位属于器件1,中间5位属于器件2,后4位属于器件3。若只想操作器件2,需给器件1和3写入BYPASS指令(全1),使它们的DR缩短为1位,从而减少扫描开销。

多器件级联时,BYPASS指令的作用不仅是"跳过",更是"缩短扫描链"。链上N个器件若全部BYPASS,一次DR扫描只需N位(每个器件1位),而非各器件DR宽度之和。

一次完整的JTAG操作时序

以读取IDCODE为例,典型序列为:从Run-Test/Idle出发,TMS=1进入Select-DR-Scan,再TMS=1进入Select-IR-Scan,TMS=0进入Capture-IR,TMS=0进入Shift-IR,此时保持TMS=0并移入IDCODE指令码(如4位0000),移完后TMS=1进入Exit1-IR,TMS=1进入Update-IR,指令生效。随后TMS=1回到Select-DR-Scan,TMS=0进入Capture-DR,TMS=0进入Shift-DR,保持TMS=0移出32位IDCODE,最后经Exit1-DR、Update-DR回到Idle。

整个过程可以用下面的信号链与状态迁移图来理解:TMS的每一位决定状态走向,TDI/TDO在Shift态完成数据交换,IR先选中目标,DR再承载数据。

TAP状态机与IR/DR扫描路径 Test-Logic-Reset Run-Test/Idle Select-DR-Scan Select-IR-Scan Capture-DR Shift-DR Update-DR Capture-IR Shift-IR Update-IR TMS=0 TMS=0 TMS=0 移位 TMS=0 移位 操作范式: ① 经Select-IR-Scan → Shift-IR 写入指令码(如IDCODE=0000)→ Update-IR 生效 ② 经Select-DR-Scan → Shift-DR 移出/移入数据 → Update-DR 更新;TMS在Shift态必须保持0 ③ 多器件级联时,非目标器件写BYPASS(全1),DR缩短为1位,降低扫描开销

多器件级联的寻址计算

假设一条链上有三个器件:器件A(IR=4位,IDCODE=0x1)、器件B(IR=5位,IDCODE=0x2)、器件C(IR=4位,IDCODE=0x3)。若只想读取器件B的IDCODE,需要:

  1. 计算IR总宽度:4+5+4=13位。
  2. 构造IR扫描数据:器件A写BYPASS(4位全1),器件B写IDCODE(5位00010),器件C写BYPASS(4位全1)。移入顺序为1111 00010 1111(先移入的位最终位于链末端,具体顺序取决于TDI到TDO的方向,需按器件在链中的物理顺序排列)。
  3. Update-IR后,器件B选中IDCODE,器件A和C选中BYPASS。
  4. DR扫描时,器件A和C各贡献1位BYPASS,器件B贡献32位IDCODE,总DR宽度为1+32+1=34位。移出34位后,中间32位即为器件B的IDCODE。

这个计算过程是JTAG调试器自动完成的,但理解它有助于排查"IDCODE读错""链上器件识别失败"等问题。常见故障包括:IR宽度配置错误导致指令错位、TMS时序不满足建立/保持时间、TCK频率过高导致长链采样失败、TRST未正确释放等。

多器件级联时,若某个器件的IR宽度配置错误,会导致后续所有器件的指令全部错位,表现为IDCODE读取异常或DP/AP访问失败。排查时应先用已知单器件验证,再逐步扩展链长。

与CoreSight调试的关系

在ARM CoreSight架构中,JTAG是访问DAP(Debug Access Port)的物理层之一。调试器通过JTAG的IR/DR机制访问DAP中的DP和AP寄存器,进而读写AHB-AP或APB-AP,最终访问目标芯片的内存和外设。因此,JTAG协议基础直接决定了TRACE32等调试工具能否正确建立连接。当连接失败时,首先应确认的是:TAP状态机是否进入正确状态、IR指令码是否匹配目标芯片、链上器件顺序和IR宽度是否与配置文件一致。