[hpm_application] 先楫硬件SPI模拟JTAG调试协议实现(一)
周末愉快!!
一、前言
本篇也是基于先楫单片机的调试器实现,模拟JTAG部分还是一样分为几篇进行阐述。对于JTAG协议,在ARM cortex-M中相对于SWD来说,并不常用。但随着riscv的发展,标准的riscv debug也是使用JTAG,JTAG对于调试器来说还是有一席之地的。
SPI模拟JTAG的文章,会分开几篇进行阐述,包括单SPI实现JTAG,双SPI实现JTAG,实际效果以及代码开源。
本篇使用先楫单SPI模拟JTAG时序原理,然后依次以IO模拟JTAG,FT2232,jlinkV11 plus的时序波形进行比较。
对于模拟SWD时序的实现,可参考- 基于先楫单片机的调试器制作之路
二、JTAG状态机
JTAG协议也就是IEEE 1149.1标准,起初是为了测试集成电路的逻辑信号提供的标准化协议,后扩展使用JTAG接口去做debug进行软件的数据寄存器、地址总线等调试。本文不做详细阐述,具体可参阅IEEE1149.1标准文档。
这里阐述下其状态机已经相关JTAG引脚作用。
(一)TAP控制器状态机
如下图的TAP控制器,所有的JTAG操作都是由以下16个同步状态机控制构成,状态的跳转由TMS的状态决定,左边代表控制数据寄存器(DR),右边代表控制指令寄存器(IR)。
比如DR一次完成的传输必须按照以下状态机进行,在一次CLOCK周期内
1、TMS=1,状态机由RUN_TEST/IDLE切换到SELECT_DR_SCAN
2、TMS=0,SELECT_DR_SCAN切换到CAPTURE_DR
3、TMS=0, CAPTURE_DR切换到SHIFT_DR,在这阶段TDO/TDI开始串行输入输出
4、TMS=1,SHIFT_DR切换到EXTI1_DR,这里也是SHIFT阶段最后一个bit传输。
5、TMS=0,EXTI1_DR切换到PAUSE_DR
6、TMS=1,PAUSE_DR切换到EXTI2_DR
7、TMS=1,EXTI2_DR切换到UPDATE_DR
8、TMS=0,UPDATE_DR切换到RUN_TEST/IDLE
(二)JTAG引脚作用
在1149.1标准中,定义了必须使用的JTAG引脚:TDI TDO TMS TCK
从上图简单概括就是:
TCK 时钟,上升沿捕获输入,下降沿变更输出。
TMS 状态选择,仿真器在 TCK 下降沿输出,被测芯片在 TCK 上升沿捕获。
TDI 串行数据输入,仿真器在 TCK 下降沿输出,被测芯片在 TCK 上升沿捕获。
TDO 串行数据输出,被测芯片在 TCK 下降沿输出,仿真器在 TCK 上升沿捕获。
三、单SPI模拟JTAG实现
在上述阐述的JTAG时序,在单SPI实现上使用GPIO模拟JTAG TMS切换,而SPI的SCLK,MISO,MOSI分别模拟JTAG的TCK,TDI,TDO。以下参考:
从时序上看,SPI需要SCLK空闲时为低电平,第一个边沿采集(数据在SCLK的上升沿被采集)。也就是SPI模式0,在hpm_sdk中可定义:
在单SPI模拟JTAG有三个比较棘手的问题,也是极大拖累一次传输的带宽利用的问题:
(一)除SHIFT_DR/IR状态下的其他状态切换问题
由于每次状态的切换需要由TMS决定,除了SHIFT可保持TMS为低。导致带来的一个问题每个状态的切换都只能一次SPI位时钟,也就是1位SPI传输。
在一次SPI传输中,需要配置位宽,传输的长度,开启传输等寄存器,从赋值这几个寄存器的指令时间,比IO翻转一次赋值可能慢,唯一能加速的就是SHIFT数据移位阶段的提升。
(二)SHIFT_DR/IR状态最后一位的问题
shift_dr/ir状态的数据最后一位移位是在TMS切换到EXTI1_DR/IR时候完成,这也导致shift状态因为最后一位而导致TCK不连续下降了带宽利用。
(三)DAP源码对JTAG序列的处理问题
由于DAP源码的通用性,加之JTAG状态机存在的以上特殊点,DAP源码对于JTAG序列的处理也是分开为不同状态机的分包处理。
针对以上的问题,在不改变DAP源码的情况下,可根据先楫SPI的功能进行些许优化 。
(一)SPI的直接引脚控制功能
先楫的HPM5300系列的SPI有个直接引脚控制功能,该功能可以通过直接控制SPI的相关引脚实现特定时序。这个功能需要注意的是,但再次使用SPI传输时,需要关闭掉该功能。
这个可以在1位传输阶段,比如TCK的翻转以及TDI,TDO的赋值,能相对于IO模拟和SPI单bit传输提高一定的传输效率。
(二)SPI的FIFO利用
先楫HPM5300具有8个字的FIFO,总共算起来有32字节的FIFO,这对于JTAG的序列传输是相当足够的。
可根据FIFO的剩余依次赋值对应的TDI或者TDO。
四、单SPI效果性能
本验证使用openocd烧录下载HPM6750,使用RAM下载,jlinkV11 Plus使用segger gdb server(但无参考意义,因为烧录过程有读取过程损失)。
openocd设置的频率都是15M
波形使用一次TAP DR 41bit传输,从SELECT_DR_SCAN到UPDATE_DR阶段,计算一次传输所消耗的时间。
单SPI模拟的JTAG的一次DR传输在15M下5.878us,在25M下4.776us,可见通过提高SPI频率是可以提升TAP一次传输效率。
(一)相比于IO模拟的TAP传输的9.44us,单SPI模拟JTAG可提升两倍以上性能。
(二)相比与FT2232的15Mclk,单SPI模拟JTAG弱于50%性能。
(三)相比与Jlink V11plus的15M clk,单SPI模拟JTAG弱于96%性能。
(四) openocd下,FT2232和hpm5301使用单SPI模拟JTAG,15M固件烧录如下,FT2232 374KB/s,而Hpm5301使用单SPI模拟JTAG 279KB/S,但相对IO模拟的速度160KB/S已经提升不少。
在上述的性能比较中可知,单SPI对于带宽的利用不如FT2232和Jlink,这是由于JTAG时序状态切换不连续引起的时间损耗。
五、总结
1、对比IO模拟JTAG,单SPI模拟JTAG相对来说提升两倍性能以上,并且频率可调整。
2、对比于市面的FT2232,单SPI模拟JTAG的烧录速度明显较弱。
3、通过FT2232和JLINK时序观测,要保证其TAP传输阶段带宽最大化,必须保证TCK传输连续化以及TMS同步。要实现该性能,可通过双SPI模拟实现JTAG,一个SPI作为从机推TMS,一个SPI作为主机推TCK, TDI, TDO。这也是下篇文章的阐述内容,敬请期待。