96SEO 2026-02-19 12:02 15
JTAG是一种国际标准的调试方式(IEEE1149.1)#xff0c;而SWD是ARM开发的。

标准JTAG采用四线方式#xff0c;分别是TCK、…1.JTAG简介
Group)而ARM支持的调试方式有JTAG和SWD(Serial
JTAG是一种国际标准的调试方式(IEEE1149.1)而SWD是ARM开发的。
标准JTAG采用四线方式分别是TCK、TMS、TDI和TDO有一个可选的TRST引脚。
在调试时需要用到一个工具比如JLink或者CMSIS-DAP对于这个工具在这里称为JTAG主机(JTAG
host)而嵌入在芯片内部的JTAG称为JTAG从机(JTAG
slave)需要注意的是上面这些信号的输入输出方向是对于JTAG从机来说的。
下文中如无特别说明JTAG都是指JTAG从机。
一个JTAG主机可以同时对多个JTAG从机进行调试这通过JTAG扫描链(JTAG
Port)控制器(或者说状态机)通过TCK和TMS信号来改变状态机的状态。
这个状态机的核心是两路SCAN分别是IR
箭头上的0或1表示的是TMS信号的电平。
JTAG在每一个TCK信号的上升沿采样TMS信号和TDI信号决定状态机的状态是否发生变化在每一个TCK信号的下降沿输出TDO信号。
可以看到无论TAP目前处于哪一个状态只要TMS保持高电平并持续5个TCK时钟则TAP一定会回到Test-Logic-Reset状态。
register)寄存器IR寄存器决定要访问的是哪一个DR寄存器。
DR寄存器有IDCODE、BYPASS等。
在Test-Logic-Reset状态下IR寄存器默认选择的是IDCODE这个DR寄存器。
调试模块在CPU芯片设计里是最为不起眼的但又是最为复杂的模块之一大部分开源的处理器IP都没有调试模块。
目前RISC-V的官方调试上位机是openocd调试工具可以是JLink或者CMSIS-DAPRISC-V调试系统框架如图3所示。
Hardware可以理解为JLink或者CMSIS-DAP这样的调试工具第三部分就是嵌入在芯片内部的调试模块。
在调试模块内部与调试工具直接交互的是DTM模块DTM模块通过DMI接口与DM模块交互。
在DTM模块里实现了一个TAP控制器(状态机)其中IR寄存器的长度最少为5位当TAP控制器复位时IR的值默认为5’b00001即选择的是IDCODE寄存器。
DTM模块的寄存器(DR寄存器)定义如图4所示。
其中红色框起来的寄存器是必须要实现的。
下面简单介绍一下这几个寄存器。
当TAP状态机复位时IR寄存器的值默认为0x01即选择的是IDCODE寄存器。
IDCODE寄存器的每一位含义如图5所示。
IDCODE是只读寄存器。
Manufld只读厂商号遵循JEP106标准分配实际中可为任意值只要不与已分配的厂商号冲突即可
主机在Run-Test-Idle状态停留的时钟周期数0表示不需要进入Run-Test-Idle状态1表示进入Run-Test-Idle状态后可以马上进入下一个状态以此类推。
dmistat只读上一次操作的状态。
0表示无出错1或者2表示操作出错3表示操作还未完成。
version只读实现所对应的spec版本0表示0.11版本1表示0.13版本。
op可读可写读或者写这个域时有不同的含义。
当写这个域时写0表示忽略address和data的值相当于nop操作写1表示从address指定的寄存器读数据写2表示把data的数据写到address指定的寄存器。
写3为保留值。
当读这个域时0表示上一个操作正确完成1为保留值2表示上一个操作失败这个状态是会被记住的因此需要往dtmcs寄存器的dmireset域写1才能清除这个状态。
3表示上一个操作还未完成。
在Update-DR状态时DTM开始执行op指定的操作。
在Capture-DR状态时DTM更新data域。
haltreq只写写1表示halt(暂停)当前hart(hart表示CPU核存在多核的情况)。
resumereq只能写1写1表示resume(恢复)当前hart即go。
hartreset可读可写写1表示复位DM模块写0表示撤销复位这是一个可选的位。
ackhavereset只能写1写1表示清除当前hart的havereset状态。
hasel可读可写0表示当前只有一个已经被选择了的hart1表示当前可能有多个已经被选择了的hart。
hartsello可读可写当前选择的hart的低10位。
1位表示一个hart。
hartselhi可读可写当前选择的hart的高10位。
1位表示一个hart。
如果只有一个hart那么hasel的值为0hartsello的值为1hartselhi的值为0。
setresethaltreq只能写1写1表示当前选择的hart复位后处于harted状态。
clrresethaltreq只能写1写1表示清除setresethaltreq的值。
ndmreset可读可写写1表示复位整个系统写0表示撤销复位。
dmactive可读可写写0表示复位DM模块写1表示让DM模块正常工作。
正常调试时此位必须为1。
dmstatus寄存器是一个只读寄存器每一位含义如图10所示。
impebreak1表示执行完progbuf的指令后自动插入一条ebreak指令这样就可以节省一个progbuf。
当progbufsize的值为1时此值必须为1。
anyhavereset1表示当前选择的hart至少有一个已经复位。
allresumeack1表示当前选择的所有hart已经应答上一次的resume请求。
anyresumeack1表示当前选择的hart至少有一个已经应答上一次的resume请求。
allnonexistent1表示当前选择的hart不存在于当前平台。
anynonexistent1表示至少有一个选择了的hart不存在于当前平台。
allrunning1表示当前选择的hart都处于running状态。
anyrunning1表示至少有一个选择了的hart处于running状态。
allhalted1表示当前选择的hart都处于halted状态。
anyhalted1表示至少有一个选择了的hart处于halted状态。
au***nticated0表示使用DM模块之前需要进行认证1表示已经通过认证。
authbusy0表示可以进行正常的认证1表示认证处于忙状态。
hasresethaltreq1表示DM模块支持复位后处于halted状态0表示不支持。
confstrptrvalid1表示confstrptr0~3寄存器保存了配置字符串的地址。
version0表示DM模块不存在1表示DM模块的版本为0.112表示DM模块的版本为0.13。
abstract控制和状态寄存器(abstractcs0x16)
busy只读1表示abstract命令正在执行当写command寄存器后该位应该马上被置位直到命令执行完成。
cmderr可读、只能写1cmderr的值仅当busy位为0时有效。
0表示无错误1表示正在操作command、abstractcs、data或者progbuf寄存器2表示不支持当前命令3表示执行命令时出现异常4表示由于当前hart不可用或者不是处于halted/running状态而不能被执行5表示由于总线出错(对齐、访问大小、超时)导致的错误7表示其他错误。
写1清零cmderr。
当写这个寄存器时相应的操作就会被执行。
command寄存器只能写定义如图12所示。
cmdtype只写命令类型0为表示访问寄存器1表示快速访问2表示访问内存。
aarsize2表示访问寄存器的最低32位3表示访问寄存器的最低64位4表示访问寄存器的最低128位。
如果大于实际寄存器的大小则此次访问是失败的。
aarpostincrement1表示成功访问寄存器后自动增加regno的值。
transfer0表示不执行write指定的操作1表示执行write指定的操作。
write0表示从指定的寄存器拷贝数据到arg0指定的data寄存器。
1表示从arg0指定的data寄存器拷贝数据到指定的寄存器。
当write0transfer1时从regno指定的寄存器拷贝数据到arg0对应的data寄存器。
当write1transfer1时从arg0对应的data寄存器拷贝数据到regno指定的寄存器。
即当访问的寄存器位数为32位时arg0对应data0寄存器arg1对应data1寄存器arg2对应data2寄存器。
aamvirtual0表示访问的是物理地址1表示访问的是虚拟地址。
aamsize0表示访问内存的低8位1表示访问内存的低16位2表示访问内存的低32位3表示访问内存的低64位4表示访问内存的低128位。
aampostincrement1表示访问成功后将arg1对应的data寄存器的值加上aamsize对应的字节数。
write0表示从arg1指定的地址拷贝数据到arg0指定的data寄存器1表示从arg0指定的data寄存器拷贝数据到arg1指定的地址。
当write0时从arg1指定的地址拷贝数据到arg0指定的data寄存器。
当write1时从arg0指定的data寄存器拷贝数据到arg1指定的地址。
当aampostincrement1时增加arg1对应的data寄存器的值。
sbbusyerror只读写1清零当debugger要进行system
sbreadonaddr可读可写1表示每次往sbaddress0寄存器写数据时将会自动触发system
sbaccess可读可写访问的数据宽度0表示8位1表示16位2表示32位3表示64位4表示128位。
bus访问后自动将sbaddress的值加上sbaccess的大小(字节)。
sbreadondata可读可写1表示每次从sbdata0寄存器读数据后将自动触发system
sberror可读写1清零0表示无错误1表示超时2表示访问地址错误3表示地址对齐错误4表示访问大小错误7表示其他错误。
可读可写如果sbcs寄存器中的sbasize的值为0那么此寄存器可以不用实现。
如果读取成功并且sbcs.sbautoincrement的值为1则增加sbaddress的值。
可读可写如果sbcs寄存器中的所有sbaccessxx的值都为0那么此寄存器可以不用实现。
如果写成功并且sbcs.sbautoincrement的值为1则增加sbaddress的值。
如果sbcs.sbautoincrement的值为1则增加sbaddress的值。
如果sbcs.sbreadondata的值为1则开始下一次读操作。
RISC-V官方支持的调试器上位机是openocd。
openocd是地表最强大(没有之一)的开源调试上位机支持各种target(ARM(M、A系列)、FPGA、RISC-V等)支持各种调试器(Jlink、CMSIS-DAP、FTDI等)支持JTAG和SWD接口。
这里不打算详细分析整个openocd的实现只是重点关注针对RISC-V平台的初始化、读写寄存器和读写内存这几个流程。
$_TARGETNAME第一行设置TCK的时钟为1000KHz。
第二行表示不支持通过TRST引脚复位只支持TMS为高电平并持续5个TCK时钟这种方式的复位。
当V4L2遇上Gstreamer第七行指定生成一个IR寄存器长度为5位、IDCODE为0x1e200a6d的JTAG
这里的target是指riscv对于riscv首先会读取dtmcontrol这个寄存器因为openocd支持0.11和0.13版本的DTM通过这个寄存器可以知道当前调试的DTM是哪一个版本。
这里选择0.13版本来分析。
通过读取dtmcontrol还可以知道idle、abits这些参数。
接下来会将dmcontrol这个寄存器的dmactive域写0后再写1来复位DM模块。
接下来再读取dmstatus判断version域是否为2。
接下来还会读取sbcs和abstractcs寄存器最后就是初始化每一个hart的寄存器。
读寄存器时先构建command寄存器的内容首先将cmdtype的值设为0aarsize的值设为2(寄存器的宽度为32位)transfer的值设为1regno的值设为要读的寄存器的number其他值设为0然后写到command寄存器里。
然后一直读取abstractcs寄存器直到abstractcs寄存器的busy位为0或者超时。
然后再判断abstractcs寄存器的cmderr的值是否为0如果不为0则表示此次读取寄存器失败如果为0则继续读取data0寄存器这样就可以得到想要读的寄存器的值。
写寄存器时先将需要写的值写到data0寄存器然后构建command寄存器的内容首先将cmdtype的值设为0aarsize的值设为2(寄存器的宽度为32位)transfer的值设为1write的值设为1regno的值设为要写的寄存器的number其他值设为0然后写到command寄存器里。
然后一直读取abstractcs寄存器直到abstractcs寄存器的busy位为0或者超时。
然后再判断abstractcs寄存器的cmderr的值是否为0如果不为0则表示此次写寄存器失败如果为0则表示写寄存器成功。
如果progbufsize的值大于等于2则会优先使用通过执行指令的方式来读取内存。
这里不分析这种方式而是分析使用system
先将sbcs寄存器的sbreadonaddr的值设为1sbaccess的值设为2(32位)然后将要读内存的地址写入sbaddress0寄存器。
接着读sbdata0寄存器最后读sbcs寄存器如果其中的sbbusy、sberror和sbbusyerror都为0则从sbdata0读取到的内容就是要读的内存的值。
先将要写的内存地址写到sbaddress0寄存器然后将要写的数据写到data0寄存器最后读sbcs寄存器如果其中的sbbusy、sberror和sbbusyerror都为0则此次写内存成功。
通过在STM32F103C8T6上实现(模拟)RISC-V调试标准进一步加深对RISC-V
使用STM32的四个GPIO作为JTAG信号的四根线其中TCK所在的引脚设为外部中断即上升沿和下降沿触发方式实现了可以通过openocd以RISC-V的调试标准来访问STM32的寄存器和内存。
程序流程如图19所示完整的工程代码见[2]。
verilog的实现见[3]。
一个从零开始写的易懂的RISC-V处理器核tinyriscv。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback