news 2026/6/23 19:39:30

OpenOCD JTAG协议开发完全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenOCD JTAG协议开发完全指南

OpenOCD JTAG协议开发完全指南

版本: 1.0
日期: 2026年1月
适用范围: RISC-V调试、FPGA开发、嵌入式系统调试


目录

  1. JTAG基础概念
  2. OpenOCD架构
  3. JTAG协议层次
  4. JTAG状态机
  5. IR/DR扫描操作
  6. OpenOCD API详解
  7. RISC-V调试规范
  8. 实际应用案例
  9. 常见问题排查

JTAG基础概念

什么是JTAG?

JTAG (Joint Test Action Group) 是一个工业标准接口,用于:

  • 芯片测试- 制造后验证芯片功能
  • 边界扫描- 访问芯片内部逻辑
  • 在系统编程- 无需特殊编程器的固件烧写
  • 调试- 实时访问处理器状态和内存

JTAG的四线接口

TCO (Test Clock Out) ← 时钟信号,由主控端驱动 TDI (Test Data In) ← 数据输入线 TDO (Test Data Out) → 数据输出线 TMS (Test Mode Select) ← 控制线,选择状态机状态 (可选) TRST (Test Reset) ← 异步复位信号

JTAG链

┌─────────────────────────────────────┐ │ PC/主控设备 (USB-JTAG适配器) │ │ (OpenOCD运行于此) │ └─────────────┬───────────────────────┘ │ TCO, TDI, TDO, TMS │ ┌─────────────▼───────────────────────┐ │ TAP 1 (device 1) │ │ ┌──────────────────────────────┐ │ │ │ TAP Controller │ │ │ │ (状态机) │ │ │ │ ┌────────────────────────┐ │ │ │ │ │ IR (指令寄存器) │ │ │ │ │ │ DR (数据寄存器) │ │ │ │ │ └────────────────────────┘ │ │ │ └──────────────────────────────┘ │ └──────────────┬──────────────────────┘ │ 级联到下一个设备 ┌──────────────▼──────────────────────┐ │ TAP 2 (device 2) │ │ ... │ └─────────────────────────────────────┘

在我们的KU060系统中

  • TAP 1: FPGA本身 (Xilinx Kintex UltraScale)
  • TAP 2: Nuclei RISC-V处理器

OpenOCD架构

分层架构

┌──────────────────────────────────────────────┐ │ 用户接口层 │ │ ├─ TCL命令 (mdw, mww, halt, resume等) │ │ ├─ GDB协议 (arm-none-eabi-gdb) │ │ └─ 远程调试接口 (TCP/IP) │ └────────────────┬─────────────────────────────┘ │ ┌────────────────▼─────────────────────────────┐ │ 目标相关层 (Target Layer) │ │ ├─ RISC-V调试器 (riscv.c) │ │ ├─ ARM调试器 │ │ ├─ 通用内存访问接口 │ │ └─ 寄存器管理 │ └────────────────┬─────────────────────────────┘ │ ┌────────────────▼─────────────────────────────┐ │ JTAG核心层 (JTAG Core) │ │ ├─ TAP扫描处理 │ │ ├─ 队列管理 (command queue) │ │ ├─ 状态机管理 │ │ └─ IR/DR操作 │ └────────────────┬─────────────────────────────┘ │ ┌────────────────▼─────────────────────────────┐ │ 驱动层 (Adapter Layer) │ │ ├─ FTDI驱动 (USB-JTAG适配器) │ │ ├─ 并口JTAG驱动 │ │ ├─ 网络JTAG驱动 │ │ └─ 其他调试接口驱动 │ └────────────────┬─────────────────────────────┘ │ └────────────────▼─────────────────────────────┘ 物理JTAG接口 (TCO, TDI, TDO, TMS)

关键文件位置

文件/目录说明
src/jtag/JTAG核心实现
src/jtag/core.cJTAG队列和TAP管理
src/jtag/drivers/硬件接口驱动
src/target/目标处理器支持
src/target/riscv/RISC-V支持 (riscv.c, riscv-013.c)
tcl/TCL脚本和配置
tcl/interface/接口配置文件
tcl/target/目标配置文件

JTAG协议层次

物理层 (Physical Layer)

时钟频率: 通常 0.1MHz - 50MHz

  • 我们的系统: 1MHz (稳定性考虑)
  • 公式:clock_speed = adapter_freq / 1MHz

信号完整性

TCO (上升沿采样) └─▁▁▁▔▔▔▁▁▁▔▔▔▁▁▁ TMS/TDI (下降沿建立) └─▁▁▔▔▔▁▁▁▔▔▔▁▁▁▔ TDO (旧数据有效) └─XXXX▔▔▔XXXX▔▔▔XXXX ▲ TCO下降沿后有效

传输方向

  • MSB优先 (Most Significant Bit First)
  • 移位寄存器的工作原理类似SPI

寄存器层 (Register Level)

指令寄存器 (Instruction Register - IR)

目的: 选择要操作的数据寄存器

┌────────────────────────────┐ │ JTAG指令集 (IR) │ ├────────────────────────────┤ │ IDCODE | 0x01 │ │ DTMCS | 0x10 │ │ DMI | 0x11 │ │ BYPASS | 0x1F │ │ (其他...) | 芯片相关 │ └────────────────────────────┘

IR扫描流程

1. 进入 IR 扫描状态 2. 在32个TCO周期内串行输入指令位 3. 同时从TDO读出旧指令 4. 指令在离开JTAG扫描链时锁存到IR中
数据寄存器 (Data Register - DR)

包含类型

  • IDCODE DR: 芯片ID (32位)

    ┌─────────────────────────────────────┐ │ Bit 31-28: 版本号 (Version) │ │ Bit 27-12: 部件编号 (Part Number) │ │ Bit 11-1: 制造商代码 (Manuf ID) │ │ Bit 0: 固定为 1 │ └─────────────────────────────────────┘
  • DTMCS DR: 调试模块控制/状态 (32位)

    ┌─────────────────────────────────────┐ │ Bit 31-16: 版本 │ │ Bit 15-12: 地址位数 (abits) │ │ Bit 11-10: 访问大小 (access) │ │ Bit 9-0: 其他状态位 │ └─────────────────────────────────────┘
  • DMI DR: 调试模块接口 (34-50位,取决于配置)

    ┌──────────────────────────────────────┐ │ Bit [1:0]: 操作/响应码 (op) │ │ Bit [33:2]: 数据 (data) │ │ Bit [40:34]: 地址 (addr) │ │ (其他bits可能因实现而异) │ └──────────────────────────────────────┘

命令层 (Command Level)

通过DMI接口发送调试命令:

/* 访问调试寄存器的DMI命令 */typedefstruct{uint32_taddr;/* 目标寄存器地址 */uint32_tdata;/* 数据 (32位) */uint8_top;/* 操作码: 0=noop, 1=read, 2=write */}dmi_cmd_t;/* DMI响应 */typedefstruct{uint32_tdata;/* 返回的数据 */uint8_tresp;/* 响应码: 0=ok, 1=busy, 2=error */}dmi_resp_t;

常用调试寄存器

地址名称说明
0x04DMCONTROL调试模块控制 (halt, resume等)
0x11HARTINFO硬件线程信息
0x40SBCS系统总线控制
0x39SBDATA0系统总线数据0
0x3aSBDATA1系统总线数据1

JTAG状态机

TAP状态机 (TAP State Machine)

标准IEEE 1149.1定义的16个状态和转移:

┌──────────────────┐ │ Test-Logic-Reset │ (初始状态) │ └────────┬──────────┘ │ TMS=0 ▼ ┌──────────────────────────────────┐ │ Run-Test/Idle │ │ (等待状态) │ └────────┬──────────────┬──────────┘ │ │ TMS=1 │ │ TMS=1 ▼ ▼ ┌────────────────┐ ┌─────────────────┐ │ Select-DR-Scan │ │ Select-IR-Scan │ └────────┬───────┘ └────────┬────────┘ │ │ TMS=0 TMS=0 │ ▼ ▼ ┌─────────────────┐ ┌────────────────┐ │ IR-Shift │ │ Capture-DR │ │ (输入IR指令) │ └────────┬───────┘ └────────┬────────┘ │ TMS=1 │ TMS=1 ▼ ▼ ┌────────────────┐ ┌─────────────────┐ │ Shift-DR │ │ IR-Exit1 │ │ (读写DR数据) │ └────────┬────────┘ └────────┬───────┘ │ TMS=1 │ TMS=1 ▼ ▼ ┌─────────────────┐ ┌────────────────┐ │ IR-Pause │ │ DR-Exit1 │ │ (可暂停) │ └────────┬───────┘ └────────┬────────┘ │ TMS=1 │ TMS=0 或 TMS=1 ▼ ▼ (两者都回到对应的Update) ┌────────────────┐ ┌─────────────────┐ │ DR-Pause │ │ IR-Update │ │ (可暂停) │ │ (更新IR) │ └────────┬───────┘ └────────┬────────┘ │ │ TMS=0 TMS=0 │ ▼ 或 TMS=1 │ ┌─────────────────┐ ▼ │ Run-Test/Idle │ ◄─ 循环 ┌────────────────┐ └─────────────────┘ │ DR-Update │ │ (锁存DR数据) │ └────────┬───────┘ │ TMS=0 └──► Run-Test/Idle

关键状态说明

状态说明用途
Test-Logic-Reset复位状态初始化,TAP复位
Run-Test/Idle闲置等待下一条命令
Select-DR-Scan选择DR准备DR操作
Capture-DR捕获DR并行加载移位寄存器
Shift-DR移位DR串行输入/输出数据
DR-Exit1DR退出1退出移位状态
DR-PauseDR暂停可选暂停点
DR-Update更新DR将移位结果锁存
Select-IR-Scan选择IR准备IR操作
Shift-IR移位IR输入新指令
IR-Exit1IR退出1退出移位状态
IR-PauseIR暂停
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/19 15:26:55

Elasticsearch近实时搜索揭秘:1秒内可查如何实现?

当你在 Kibana 中查询刚生成的日志,或在电商网站搜索刚上架的商品时,可能会好奇:数据写入后不到 1 秒就能搜到,这是如何实现的? 这背后就是 Elasticsearch (ES) 的“近实时”(Near Real-Time, NRT&#xff…

作者头像 李华
网站建设 2026/6/13 7:16:44

SSM241的房屋中介出租出售系统vue

目录系统概述技术架构核心功能创新点应用价值开发技术源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!系统概述 SSM241房屋中介出租出售系统基于Vue.js前端框架与SSM(SpringSpringMVCMyBatis)后端架构开发&#…

作者头像 李华
网站建设 2026/6/16 8:38:25

萤石开放平台 设备运维 | 远程设备调试 快速入门

远程设备调试 1. 前置条件 设备要求: 设备绑定在当前账号下当前设备状态:在线设备能力要求:支持设备远程调试能力 2. 使用流程 2.1进入找到对应设备,并开启调试 在萤石开放平台控制台-设备管理页面中找到您需要调试的设备&a…

作者头像 李华
网站建设 2026/6/15 8:00:44

AtCoder Beginner Contest竞赛题解 | AtCoder Beginner Contest 440

​欢迎大家订阅我的专栏:算法题解:C与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选…

作者头像 李华
网站建设 2026/6/18 16:30:18

如何用ChatGPT提升开发效率?实战技巧大公开

ChatGPT在软件测试中的效率革命 随着AI技术的快速发展,ChatGPT正成为测试工程师的智能协作者。本文聚焦六大核心场景,结合可落地的操作指南,帮助测试人员将AI能力深度融入工作流。 一、智能测试用例生成:覆盖度提升300%的秘诀 1…

作者头像 李华
网站建设 2026/6/22 12:46:12

JavaScript 数组合并性能优化:扩展运算符 vs concat vs 循环 push

在日常开发中,我们经常需要合并数组,比如批量导入数据、分页加载列表、处理大量日志等场景。当数组规模较小时,用什么方法都差不多;但当数组达到成千上万条时,选择不当的方法可能会导致栈溢出或内存飙升。 今天我们就…

作者头像 李华