资讯动态

JTAG调试接口深度解析:协议、状态机与实战排查

发布时间:2026/8/26 1:44:27 来源:尧图企业网站定制
1. JTAG到底是一门什么“语言”先聊个场景。你手上有一块新板子MCU贴上去了电源、时钟、复位都检查过唯独就是连不上调试器。报错信息翻来覆去就一句话Target not found。这种时候很多人的第一反应是“芯片坏了”或者“焊接虚了”但实测下来很大概率是你跟板子上的芯片根本没“说上话”。因为调试器和芯片之间不是通电就行的它们之间有一套严格的通信协议这套协议就是JTAG。JTAG的全称是 Joint Test Action Group这个组织在1985年左右提出了一套边界扫描测试标准后来被接纳为 IEEE 1149.1 标准。这玩意儿最初是为了解决PCB板级测试难题的——当板子上的芯片越来越密、引脚间距越来越小飞针测试和探针测试逐渐力不从心于是大家想到在芯片内部把每个引脚都串接进一条移位寄存器链里通过这条链读引脚状态、控制引脚输出从而在不物理接触引脚的情况下完成板级互连测试。这条“链”和控制它的协议就是JTAG。但嵌入式工程师认识JTAG多半不是因为边界扫描测试而是因为它被ARM、MIPS、RISC-V等内核广泛用作调试接口。通过JTAG调试器可以读写CPU寄存器、访问内存、设置断点、单步执行、烧写Flash。换句话说JTAG不只是一条测试总线它是一套可以“接管”芯片内部状态的通用后门。你如果能把JTAG这门外语说利索调试、烧录、产线测试、安全分析都能打通。这篇文章不是照着IEEE文档翻译而是围绕实际工程里你一定会碰到的几个问题来展开JTAG引脚怎么接、TAP状态机怎么走、为什么STM32点一下“禁用JTAG”就再也连不上了、S32K的JTAG保护到底在保护什么、高云FPGA识别不到该从哪儿查起。适合刚接触嵌入式调试的新手也适合被调试器“劝退”过、想从原理层面搞明白为什么连不上的老工程师。2. 引脚定义与硬件连接四根线是怎么把芯片“撬开”的2.1 标准引脚逐个说TCK、TMS、TDI、TDO、TRSTJTAG接口的物理层很简单基础四根信号线加一根可选的复位线。先把它们各自的角色搞清楚后面看原理图才不会两眼一抹黑。TCKTest Clock测试时钟由调试主机比如JLINK、ST-LINK、OpenOCD跑在上面的PC产生是所有JTAG操作的节奏基准。TCK是单向信号只从主机流向目标芯片。TMSTest Mode Select测试模式选择同样是主机输出到芯片。TMS在TCK的上升沿被采样多个TMS比特序列组合起来驱动TAP状态机在不同状态之间跳转。TDITest Data In测试数据输入主机向芯片移位输入数据。数据在TCK上升沿被采样进入芯片内部的移位寄存器。TDOTest Data Out测试数据输出芯片向主机移位输出数据。一般是在TCK下降沿更新TDO上的数据这样主机在下一个上升沿采样时数据已经稳定。TRSTTest Reset测试复位可选信号低电平有效用来把TAP状态机异步复位到Test-Logic-Reset状态。如果不用通常直接拉高或上拉只靠TMS连续5个高电平也能让状态机回到复位态。这里有第一个极容易踩的坑TDO的数据更新边沿和TDI的采样边沿往往是错开的一个在下降沿一个在上升沿这样设计的目的是保证数据在采样窗口内稳定。所以如果你用逻辑分析仪抓JTAG时序别光看电平对不对一定要以TCK为基准去看TDI/TMS在上升沿时是否稳定TDO在下降沿后是否稳定。我之前见过有人抓波形TDO高电平只维持了半个时钟周期就开始怀疑协议有问题其实就是没搞懂边沿关系。2.2 连接方式与电平匹配为什么1.8V的板子总是连不上JTAG的电气连接说简单也简单调试器的TCK/TMS/TDI接到芯片对应引脚TDO接回来地线共地。但真正到了实际板子上有三个问题必须处理。第一个是电平匹配。老一代调试器尤其一些兼容JLINK的克隆版默认输出3.3V或5V电平而现在的MCU大量采用1.8V甚至更低的核心电压IO电平也跟随供电。直接把3.3V的TCK信号接到1.8V的芯片引脚上轻则通信不稳定重则打坏引脚。现代的调试器一般都有电平自适应功能比如J-LINK的VTref参考电压检测VTref必须接目标板的IO供电这样调试器才能输出和板子匹配的电平。有些调试器还要在软件里设置目标电压板子电平变了一定要记得同步改配置。第二个是信号完整性问题。JTAG时钟在10MHz以下时一般飞线杜邦线连接问题不大但如果你跑到20MHz、30MHz或者线缆特别长超过20cm还没有屏蔽TCK/TDI/TMS的边沿会变差TDO回来的时候数据已经乱了。这种时候不要急着怀疑芯片先把TCK降频到1MHz试一下。降频能通、升频就挂那就是信号完整性问题而不是协议配置问题。第三个是复位信号。SRST系统复位在很多JTAG调试场景里是可选的但对于连不上芯片的场景它往往是救命稻草。因为有些芯片在异常状态比如进入了低功耗模式、Flash读保护下必须由调试器拉低复位脚才能接管CPU。所以设计调试接口时我建议至少把TCK、TMS、TDI、TDO、GND五根线引出来有条件的把SRST也引出来多一根线排查问题多一条路。2.3 JTAG接口原理图设计的几个工程细节画JTAG调试接口的原理图我有几个长期积累下来的习惯分享出来能帮你少走很多弯路。第一所有JTAG信号线上串22Ω到47Ω的小电阻。这些电阻不是为了限流而是为了阻尼反射、抑制振铃特别是TCK这种高速时钟线串个小电阻能明显改善信号质量。成本几乎为零但能减少很多“玄学”问题。第二TMS、TDI建议加上拉电阻TDO一般不用加TCK如果调试器侧没有驱动能力问题也不需要额外处理。为什么TMS和TDI要上拉因为TMS线悬空时的默认电平决定了TAP状态机的行为——如果TMS悬空被噪声拉低芯片可能在你不操作的时候自己跑进移位状态导致后续通信错乱。上拉到高电平后默认状态就是Test-Logic-Reset这是最安全的。第三如果你的设计需要支持多种调试器比如既要接J-LINK又要接ST-LINK甚至要接自己做的烧录工装那JTAG接口的引脚顺序最好做成一排标准的2.54mm间距排针并且把引脚定义标注在丝印上。别小看这个产线上换调试器的时候一根线接错就能烧掉一个芯片的IO。我自己就见过因为TDI和TDO接反调试器输出直接怼到芯片输出脚上白白报废了几片样品。3. 协议核心机制TAP状态机和“移位”的本质3.1 TAP状态机一条固定路线图十六个状态来回走如果说JTAG是一门语言那TAP状态机就是这门语言的语法规则。所有JTAG操作都建立在TAP状态机的状态跳转之上。TAP状态机一共16个状态拓扑结构是固定的无论哪家芯片JTAG状态机都长一个样Test-Logic-Reset测试逻辑复位上电后的默认状态JTAG逻辑不工作对芯片正常运行无影响。Run-Test/Idle运行测试/空闲状态机在工作之前通常先停在这个状态。Select-DR-Scan / Select-IR-Scan选择数据寄存器扫描/选择指令寄存器扫描两个过渡状态用来决定接下来操作的是数据寄存器还是指令寄存器。Capture-DR / Capture-IR捕获数据/指令在这个状态芯片会把当前指令寄存器或数据寄存器的内容并行装载到移位路径里。Shift-DR / Shift-IR移位数据/指令在这个状态每来一个TCK上升沿移位路径里的数据就移动一位TDI进来的数据从一端进入TDO上的数据从另一端出去。这也是JTAG数据交换的核心动作。Exit1-DR / Exit1-IR、Pause-DR / Pause-IR、Exit2-DR / Exit2-IR、Update-DR / Update-IR一系列过渡和暂停状态用暂存的方式把移位寄存器里的数据锁存到实际的并行输出寄存器里。实际编程中你不需要手动逐个状态去跳调试器或OpenOCD的驱动库已经帮你封装好了。但理解这条路线非常重要因为排查通信问题时你总得知道主机期望芯片处于哪个状态、芯片实际处于哪个状态。举个例子当TMS信号接触不良某个上升沿采样到错误电平状态机就可能跑到一个你完全没预料到的分支上去。接下来所有通信都错位表现就是第一次能读到IDCODE后面全是垃圾数据或者干脆读不到。那状态机到底怎么“走位”呢规则很简单每个TCK上升沿TMS上的电平决定下一个状态。TMS为高走一条路TMS为低走另一条路。关键在于从Test-Logic-Reset出发TMS连续五个高电平无论之前状态是什么都能回到Test-Logic-Reset。这其实就是一个“复位”机制JTAG协议靠这个就能把状态机拉回已知状态恢复通信。所以前面提到TMS一定要上拉逻辑就在这——悬空的TMS一旦被干扰拉低状态机就乱跑了。3.2 指令寄存器与数据寄存器芯片里有一张“操作菜单”TAP状态机选定扫描路径之后真正干活的是寄存器。JTAG芯片内部有两类寄存器一类是指令寄存器IRInstruction Register一类是数据寄存器DRData Register集合。指令寄存器保存的是当前指令。IEEE 1149.1标准规定了一些公共指令比如BYPASS旁路把TDI和TDO之间只用1位移位寄存器连起来用于绕过当前芯片。在多颗芯片菊花链连接时BYPASS可以让不操作的芯片变成直通缩短整条移位链。IDCODE标识码读取把芯片的IDCODE寄存器通常是32位连接到TDI和TDO之间主机通过移位可以读出芯片的制造商、型号、版本信息。调试软件第一次连接目标时通常都会先发IDCODE指令来确认芯片身份连不上时第一步就是看能不能读到IDCODE。SAMPLE/PRELOAD采样/预装在不影响芯片正常工作的情况下把引脚状态采样到边界扫描寄存器里或者在边界扫描之前预装数据。EXTEST外部测试把边界扫描寄存器里的数据驱动到引脚上用于板级互连测试。这就是JTAG作为“测试总线”的原始用途。数据寄存器则是一组并行寄存器具体有哪些取决于芯片设计。最核心的是边界扫描寄存器Boundary Scan Register它把所有芯片引脚串成了一条移位链。此外还有BYPASS寄存器、IDCODE寄存器以及芯片厂商自定义的调试寄存器比如ARM内核的Debug Port寄存器。主机操作JTAG的基本套路是固定的先进入Shift-IR状态把一条指令的二进制编码从TDI一位一位移进去然后进入Shift-DR状态根据指令选择对应的数据寄存器再移入/移出数据。这个过程有点像你打电话的时候先拨号指令再通话数据。拨号错了后面说的内容对面根本不会理。3.3 一个IR扫描的完整时序从Test-Logic-Reset到Shift-IR把状态机跳转和寄存器移位串起来我们看一个简单的IR扫描过程。假设要读IDCODE芯片IR长度是4位。主机先把TMS连续置高5个TCK周期确保状态机进入Test-Logic-Reset。发TMS0一个TCK后进入Run-Test/Idle。发TMS1进入Select-DR-Scan再发TMS1进入Select-IR-Scan因为要操作指令寄存器不选DR。发TMS0进入Capture-IR。在这个状态芯片把当前指令可能是IDCODE指令的编码也可能是上电默认值并行放入IR移位路径。发TMS0进入Shift-IR。然后连续发多个TCK周期TMS保持低电平同时TDI上的数据逐位移入TDO逐位读出旧的指令内容。如果IR是4位就移4个时钟。移位完成后发TMS1经过Exit1-IR再发TMS1经过Update-IR把移位寄存器里的新指令锁存到实际的IR输出端。这一步很关键只有到了Update-IR指令才算真正生效。接下来再进Run-Test/Idle然后走Select-DR-Scan路径进入Capture-DR把IDCODE寄存器内容并行装载到移位路径再进Shift-DR逐位移出主机就拿到32位IDCODE了。整个过程看着繁琐但这就是JTAG“说话”的底层方式。你调试器软件点一下“Connect”背后就是这一大串状态跳位和移位操作。所以如果你在调试器与芯片之间串联一个逻辑分析仪对着波形核对状态跳转就能判断是哪一步出了问题。4. 实操过程从识别到调试的完整流程4.1 用OpenOCD连上一颗MCU从IDCODE到Flash读写前面铺垫了这么多协议层面的东西现在落到实际操作。我以OpenOCD 一块STM32F103开发板为例走一遍完整流程这套流程在全志、NXP、GD等常见芯片上也通用。首先准备好硬件连接J-LINK的TCK、TMS、TDI、TDO分别接到STM32的SWD/JTAG调试口。注意STM32的调试口是有多个复用功能的默认情况下PA13/PA14/PA15/PB3/PB4是JTAG调试引脚PA13JTMS/SWDIOPA14JTCK/SWCLKPA15JTDIPB3JTDOPB4JTRST其中PA13/PA14同时也是SWD引脚。如果这些引脚被程序重映射成了普通GPIO调试器就找不到芯片了这一点后面专门讲。然后创建OpenOCD配置文件。最简单的方式是直接用板卡厂商提供的cfg但为了理解我建议自己写一个最小配置interface jlink adapter speed 1000 transport select jtag set CHIPNAME stm32f103 jtag newtap $CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf target create $CHIPNAME.cpu cortex_m -chain-position $CHIPNAME.cpu stm32f1x newdap $CHIPNAME cpu stm32f1x dap_allow_aps 0 1这段配置里-irlen 4表示指令寄存器长度4位-ircapture 0x1是Capture-IR状态时IR里预置的值-irmask 0xf表示IR有效位掩码。这几个参数如果和芯片不符连接时会出现“TAP does not have valid IDCODE”之类的报错。配置好之后在命令行执行openocd -f interface/jlink.cfg -f myboard.cfg正常的话OpenOCD会自动检测并打印目标芯片的IDCODE信息里包含制造商和芯片型号。然后开另一个终端用telnet或直接通过OpenOCD的tcl端口执行命令flash banks halt flash write_image erase ./firmware.hex reset runhalt让CPU停下来等待调试flash write_image烧录固件reset run复位并运行。这一步顺利的话一个最基本的JTAG调试链路就算打通了。实测下来OpenOCD用JTAG方式连接STM32比SWD方式要慢一些因为JTAG协议开销大、引脚多但看到IDCODE被打出来的那一刻你会觉得前面那些协议学习都是值得的。4.2 STM32禁用JTAG之后如何恢复SWD是救命通道STM32有一个非常经典的坑默认情况下调试接口功能是完整的JTAGSWD但如果你在代码里调用了GPIO_Remap函数把JTAG引脚重映射成普通GPIO比如为了让PB3、PB4当输出口用那JTAG功能就被关闭了。一旦芯片掉电再上电程序跑起来执行到重映射代码调试器就再也连不上了。遇到这种情况别慌恢复路径有这么几种。第一种是用SWD而不是JTAG。STM32的PA13/PA14作为SWDIO/SWCLK在禁用JTAG时SWD一般还是保留的除非你把SWD也禁用。很多调试器比如ST-LINK、J-LINK都同时支持SWD和JTAG两种模式切到SWD模式再连接往往能救回来。第二种是“空片启动”法。把BOOT0引脚拉高复位后芯片从系统存储器启动bootloader用户Flash里的代码不执行JTAG引脚就不会被重映射。这时候用调试器连接注意选择JTAG或SWD把Flash擦除再恢复正常BOOT0芯片就复活了。第三种是“上电时序”法。在目标板上电瞬间快速点击连接让调试器在程序运行到重映射代码之前完成握手并halt住CPU。这个方法对时序要求高成功率不稳定但作为备用方案值得一试。我个人的建议是在开发阶段如果必须把JTAG引脚挪作他用也尽量保留SWD功能PA13/PA14并在量产固件里加一个延时窗口比如上电后500ms内检测到调试器连接就halt超过窗口再重映射引脚。这个“握手窗口”设计在产线调试时极其有用能避免板子变成“一次性”的。4.3 S32K的JTAG保护生命周期与Debug AuthenticationNXP的S32K系列在车规MCU里用得很多和STM32的简单GPIO重映射禁用不同S32K的JTAG保护做在芯片生命周期Life Cycle层面。S32K1xx系列芯片出厂时处于空白状态配置好CSEc安全模块后生命周期可以推进到不同的阶段不同阶段对JTAG访问权限有严格限制。这里要区分两个概念Debug Access和Flash Access。JTAG能连上芯片和JTAG能读写Flash是两回事。S32K的Fuse熔丝配置里有一项叫DEBUGGER_DISABLE一旦烧写置位外部调试器就只能访问有限的寄存器不能读内存、不能halt CPU、更不能读写Flash。用户程序本身可以继续跑但调试器完全拿不到控制权。如果芯片已经设置了保护而你确实需要调试那就得走NXP的Debug Authentication流程。这需要芯片在出厂时烧录过对应的Debug Credential调试凭证然后在调试器侧导入私钥和凭证文件与芯片完成双向认证后才能临时开放调试权限。这个过程不是无条件的它基于非对称加密目的是让芯片厂商在保护安全的同时给合法的开发者留一条受控的后门。所以如果你在做S32K项目第一步就要想清楚生命周期策略开发阶段不要急着把Debugger Disable熔丝烧进去等产线固件确定要锁代码了再设置保护。而且一定要保留能在开发板和量产板之间切换的调试权限管理方案否则后期发现问题想接JTAG只能干瞪眼。4.4 高云FPGA JTAG识别不到从软件到硬件的排查清单高云GOWIN的FPGA在国内用得越来越多很多人第一次接触它的JTAG配置时都会卡在“识别不到芯片”这个问题上。高云的FPGA通过JTAG下载bitstream推荐使用官方下载器如Gowin GW-UNIO-RB也支持第三方JTAG电缆配合官方软件。先检查软件层高云云源软件Gowin Software的Programmer工具里是否选择了正确的下载模式是高云下载器模式还是第三方的JTAG模式。有些版本对第三方下载器的协议支持有限表现就是“No Device Found”。另外高云的JTAG IDCODE和Xilinx/Altera不一样别拿别的FPGA的经验硬套直接看软件输出的IDCODE是否全0或全1。再检查硬件层高云FPGA的JTAG引脚TCK、TMS、TDI、TDO一般和普通IO复用如果这些引脚被设计成了普通IO且外部有上下拉电阻/其他负载会影响JTAG信号。还有一个很常见的坑——JTAG链上如果串联了多颗芯片比如CPU和FPGA共用一条JTAG链IDCODE扫描整条链才能识别到所有设备。单颗芯片的工程配置里如果只期望一颗设备而链上实际挂着好几颗就会“识别不到”。排查顺序我建议这样先量TCK是否有时钟用示波器或逻辑分析仪再看TMS能不能正常翻转然后确认TDI到芯片、TDO从芯片返回的链路是否通。这几根线里只要有一根断了或短了IDCODE就读不出来。最后才考虑下载器和软件配置问题。实测中TCK信号因为线缆过长导致的上冲/振铃导致识别失败比芯片本身坏了的情况多得多换一根短一点的屏蔽线就解决。5. JTAG保护、安全边界与产线的平衡术5.1 为什么芯片要“关闭JTAG”从调试后门到攻击面JTAG的功能越强大它作为安全攻击面的风险就越大。只要JTAG调试口是开放的攻击者就可以通过它读取Flash里的固件、修改内存数据、绕过安全校验、甚至提取密钥。正因如此几乎所有带安全需求的芯片都会提供某种形式的JTAG封禁机制。常见的封禁方式有三类。第一类是软件层面的引脚复用比如前面提到的STM32把JTAG引脚重映射成GPIO。这属于最弱的保护因为一旦boot引脚拉高绕开用户程序JTAG依然会被恢复。第二类是芯片级的熔丝/选项字节比如STM32的读保护级别RDP Level 0/1/2、NXP的Debugger Disable、Microchip的JTAG锁定位。这类保护烧进去之后即使调试器物理上连接正常也无法访问芯片内部资源。第三类是加密认证比如ARM CoreSight的JTAG调试认证、S32K的Debug Authentication需要密钥协商后才能开放调试权限是当前安全性最高的方案。从开发者角度看“关闭JTAG”是一把双刃剑。关得太早开发阶段频繁连不上调试器效率受挫关得太晚固件和密钥暴露在攻击者面前产品上市就是裸奔状态。合理的策略是分阶段控制开发板不设保护试产板用软件级保护并保留恢复通道量产板在产线最后一步统一烧写熔丝级别的保护。5.2 保护机制的实现层次代码、熔丝、还是加密选择哪种保护层次取决于你的威胁模型。如果是消费类产品对手可能只是拿调试器随便戳一戳那选项字节级别的读保护就够了。如果是车规、工控、金融支付产品攻击者有可能是专业的硬件逆向团队那必须上加密认证级别的JTAG保护。以STM32为例RDP Level 1可以禁止调试器通过JTAG/SWD读写Flash和SRAM但CPU仍可以从Flash启动运行如果攻击者把程序引导到自己的代码里通过修改栈指针等方式还是可能泄露部分内容。RDP Level 2则是永久性保护禁止一切调试访问而且不可逆。选了Level 2就意味着芯片一旦出货连你自己也无法接调试器了——所以必须在量产前确认固件全部验证完毕。NXP S32K的Debug Authentication机制又更进一步。它在芯片出厂时预置一个Root Public Key Hash开发者只有持有对应的私钥和签名过的Debug Credential才能把芯片从“锁定”状态临时解锁到“可调试”状态。每次解锁都有日志记录过期自动重新锁定。这个机制在“保护固件”和“允许售后调试”之间取了平衡代价是流程复杂度显著上升。5.3 产线烧录与固件保护的节奏把控产线上烧录固件最忌讳的就是把“烧录”和“加保护”合在一步里无脑完成。我见过一个实际案例某产品用STM32量产工序里用脚本一把梭烧固件的同时把RDP置成Level 1。然后产线测试发现有个功能需要改配置想用JTAG连板子结果发现连不上只能返工。这就是没理解保护的“不可逆”和“时间点”概念。推荐的节奏是三步走第一步烧录固件不设保护第二步跑产线测试全部通过后第三步通过同一个JTAG口下发“使能保护”指令。如果第二步发现问题板子还可以直接接调试器查原因。保护指令下发后再抽查几片板子的保护状态是否生效。这样既保证了产线效率也留了返修空间。在固件里也要留一个“售后调试”的入口。比如做一个产线测试模式上电时检测某个特定GPIO电平如果拉低就跳过安全校验并开放JTAG调试权限否则正常运行并锁定调试口。这个口子一定要做得隐蔽且可裁剪避免攻击者利用它绕过保护。6. 常见问题与排查技巧实录6.1 一张速查表覆盖90%的“JTAG连不上”场景下面这张表是我这些年调试JTAG问题时最常用到的一份清单每个问题都对应着明确的检查点。现象可能原因排查动作完全找不到设备IDCODE读不到供电异常、TCK无时钟、TMS被拉低量VCC/GND用示波器确认TCK有波形确认TMS上拉正常能识别到器件但Flash读写失败指令寄存器长度配置错误、IR捕获值不对查芯片手册的IR长度和捕获值核对OpenOCD cfg参数连接不稳定经常掉线TCK频率过高、线缆过长、信号反射降低TCK到1MHz换短屏蔽线在TCK上加串阻连接时提示“Cannot connect to target”CPU进入低功耗模式、复位引脚被拉低检查SRST连接强制复位后再连接检查低功耗配置芯片引脚被占用JTAG被禁用程序把调试引脚重映射为GPIO切SWD模式BOOT拉高绕过用户程序擦除Flash多颗芯片菊花链时IDCODE解析失败链上设备数量与配置不符、BYPASS无效在软件里配置正确的扫描链长度检查每颗芯片BYPASS指令FPGA能下载但Bitstream验证失败下载器电气不匹配、TCK速度太高换成官方下载器JTAG频率降到10MHz以下连接正常但无法读CPU寄存器CPU处于hard fault或Lockup状态硬件复位后快速halt检查看门狗是否一直在复位CPU这张表覆盖的场景看着多但归纳下来其实就是三类电气连接断了、协议配置错了、芯片自身状态锁了。排查的时候按这个优先级顺序来不要一上来就怀疑协议配置。6.2 用逻辑分析仪抓JTAG时序的实操心得JTAG问题排查到最后一层一定是抓时序。我强烈建议每个做嵌入式调试的工程师手边都备一个至少4通道、采样率100MS/s以上的逻辑分析仪配合Sigrok/PulseView这类开源软件就够了。抓JTAG时的接法CH1接TCKCH2接TMSCH3接TDICH4接TDO全部共地。触发条件设置为TMS下降沿因为这通常表示状态机开始从Run-Test/Idle向Select-DR/IR跳转是一次扫描操作的起点。抓完之后先数一下TCK脉冲个数然后对照TMS电平序列画出状态机路径核对指令长度和数据长度。有个细节要注意很多逻辑分析仪默认是异步采样如果采样率不足会漏掉短脉冲。抓JTAG时采样率至少是TCK频率的10倍以上比如TCK是1MHz至少要采10MS/s推荐25MS/s以上。如果用的是带协议解码的分析仪比如DSView的JTAG解码器还要手动设置IR长度、字节序等参数不然解码出来的数据是乱的。我见过有人拿协议解码器直接解解出来的IR全是0x0就以为芯片坏了其实是他没设置IR长度。6.3 ARM9内核JTAG的特殊性老平台也有它的脾气现在写ARM9内核比如AT91SAM9、i.MX28这类老平台的人少了但存量项目还在而且这类芯片的JTAG调试脾气和Cortex-M很不一样。ARM9是传统的ARM体系结构ARMv5它的JTAG调试接口由EmbeddedICE逻辑实现而不是Cortex-M内核那种CoreSight调试架构。JTAG连接ARM9时调试器通常需要配置一个很大的扫描链ARM7/ARM9的扫描链可能长达30到40位具体取决于芯片实现并且调试操作依赖特定的扫描链编号比如选择Chain 5作为EmbeddedICE的访问通道。如果在OpenOCD里配置ARM9时只改了-irlen没有正确配置扫描链编号连接后会出现在“Halt”时CPU反应异常。另一个坑是ARM9内部没有像Cortex-M那样内置Flash烧写算法烧写外部NOR Flash/NAND Flash基本都要先用调试器把一段烧写代码加载进SRAM然后再跳过去执行。所以ARM9的JTAG调试对调试器或OpenOCD脚本的Flash驱动配置更敏感。如果你碰上ARM9平台建议先读芯片手册里的“Debug”章节把JTAG链长度、扫描链编号、嵌入式ICE寄存器地址都列出来再调试。7. 一些测试中的体会最后分享一个我印象很深的经历。曾经调试一块带安全加密芯片的板子JTAG接口在原理图上看着没问题但每次连接都只能读到一串乱码IDCODE。花了大半天时间检查配置和时序最后发现是TDO线上并了一个0402封装的0欧电阻焊盘有点偏虚焊导致信号时通时断。换掉这颗电阻以后一切恢复正常。这个案例让我养成了一个习惯JTAG连不上的时候先怀疑物理层再怀疑协议层最后才怀疑芯片本身。因为JTAG本质上是把芯片测试接口和调试接口合二为一的“语言”它要求电气层面先把事情说清楚然后才是状态机和寄存器的事。很多时候不是芯片不配合而是你的“信号线”没有把话说清楚。最后再给一个实操小技巧如果你经常在不同板子之间切换调试建议准备一个带JTAG和SWD两种接口定义的小转接板并在每个项目里把调试接口的引脚定义、电平、默认时钟频率整理成一份表格放在项目文档里。这样换项目、换调试器、换人的时候都不用从头看原理图直接查表就能连上目标芯片。这些小习惯看着简单长期坚持下来可以帮你省掉大量重复排查的时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价