news 2026/2/9 14:31:37

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/2/8 9:45:23

计算机毕业设计springboot线上票务系统app 基于Spring Boot的移动票务管理平台开发 Spring Boot框架下的线上票务系统设计与实现

计算机毕业设计springboot线上票务系统app_ck27e (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着互联网技术的飞速发展,线上票务系统已经成为人们日常生活中不可…

作者头像 李华
网站建设 2026/2/7 14:08:21

Linux运维必备:一个LVM管理添加和扩容脚本的诞生记(完整版)

从简单需求到踩坑无数,最终炼成自动化神器。本文记录了一个LVM管理脚本的完整开发历程,包含所有踩过的坑和最终解决方案。附赠可直接使用的纯净版脚本。一、起因:一个看似简单的小需求那天,一位运维兄弟在群里求助:&qu…

作者头像 李华
网站建设 2026/2/8 17:53:09

LeetCode 379 电话目录管理系统

文章目录摘要描述题解答案题解代码分析1. 数据结构的选择2. 初始化方法3. get() 方法:分配号码4. check() 方法:检查号码是否可用5. release() 方法:释放号码6. 为什么使用 Set Array 的组合?7. 边界情况处理示例测试及结果示例 …

作者头像 李华
网站建设 2026/2/7 19:46:57

04. 引用

1.引用的基本定义与核心特性 2.引用的常见用法 3.引用 vs 指针1.引用的基本定义与核心特性 c中引用是变量的"别名", 就像一个人有本名和外号, 引用和原变量指向同一块内存地址, 操作引用就等同于操作原变量1).语法格式// 语法:类型& 引用名 原变量名…

作者头像 李华
网站建设 2026/2/9 9:11:43

当AI刺破泡沫:算力瓶颈、能源战争与资本主义的“物理转向”

如果说过去二十年的科技主旋律是“软件吞噬世界”,那么在 Jordi Visser 看来,这一章节正在剧烈翻篇。我们正处于一个甚至连“资本主义”本身都在面临终结与重构的奇点时刻。 当大众还在惊叹于 ChatGPT 的生成能力时,华尔街的敏锐资金已经嗅到了风向的改变:AI 的竞争不再仅…

作者头像 李华