1. 调试系统总览

在嵌入式开发中,调试手段通常分为两类:一类是“侵入式”调试,例如通过串口打印日志、在代码中插入 GPIO 翻转或变量快照;另一类是“非侵入式”调试,即在不改变被调试程序运行行为的前提下,借助芯片内部专门的硬件调试逻辑观察和控制 CPU。JTAG、CoreSight 与 TRACE32 正是后一条技术路线上的三个关键角色:JTAG 提供物理层的访问通道,CoreSight 提供芯片内部的调试与跟踪基础设施,TRACE32 则是运行在主机侧、通过这条通道操控 CoreSight 的调试软件与硬件工具链。

三个角色的分工

JTAG(Joint Test Action Group)最初是为边界扫描测试制定的 IEEE 1149.1 标准,它定义了一个由 TDI、TDO、TCK、TMS 四根(可选 TRST)信号组成的串行扫描链。在调试场景中,JTAG 不再只是测试接口,而是作为访问芯片内部调试寄存器的“门”。主机通过 TAP 状态机把数据串行移入 IR(指令寄存器)和 DR(数据寄存器),从而读写 DAP(Debug Access Port)等调试组件。它的本质是一条低速、可靠、标准化的寄存器访问通道。

CoreSight 是 ARM 定义的片上调试与跟踪架构。它把调试组件组织成一套可发现、可级联的结构:DAP 负责把外部 JTAG/SWD 请求转换为内部 APB 或 AXI 访问;APB-AP 用于访问 CoreSight 组件寄存器,AXI-AP 用于直接访问系统内存;CTI/CTM 用于交叉触发;ETM/PTM 负责指令跟踪;ITM/STM 负责软件事件与 printf 类跟踪;ETB/TPIU 负责跟踪数据缓存与输出。CoreSight 的价值在于,它把“控制 CPU、读写内存、采集跟踪”这些能力做成了标准化的片上基础设施,而不是依赖某个具体芯片厂商的私有方案。

TRACE32 是 Lauterbach 的调试工具,由主机端软件(PowerView)和硬件调试探头(如 Debugger、PowerTrace、CombiProbe)组成。它通过 USB、以太网或 PCIe 与主机通信,通过 JTAG、SWD、cJTAG 等接口与目标芯片连接。TRACE32 并不直接“理解”某个 CPU 的全部细节,而是通过加载对应的 CPU 支持包和 CoreSight 描述文件,把用户操作翻译成对 DAP、AP、ETM、ITM 等组件的寄存器访问。因此,TRACE32 是面向工程师的交互层与自动化层,JTAG 是物理传输层,CoreSight 是片上功能层。

嵌入式调试系统三层结构:主机工具 → 物理通道 → 片上调试基础设施 主机侧:TRACE32 PowerView • 源码级断点 / 单步 / 变量查看 • 内存读写、寄存器访问 • 跟踪数据解码与时间线分析 • 脚本自动化(.cmm)与批量测试 • 多核同步控制与 SMP 调试 调试探头:TRACE32 硬件 • USB / Ethernet / PCIe 主机接口 • JTAG / SWD / cJTAG 目标接口 • 自适应时钟与电平匹配 • PowerTrace:大容量跟踪缓存 • 实时跟踪流上传与触发输出 目标 SoC:CoreSight 架构 • DAP:JTAG/SWD → APB/AXI • APB-AP:调试组件寄存器 • AXI-AP:系统内存直接访问 • ETM / ITM / ETB / TPIU • CTI / CTM 交叉触发网络 CPU 内核 Cortex-A / R / M 运行被调试程序 调试与跟踪组件 断点单元 · 观察点 · ETM · ITM ETB 缓存 · TPIU 输出 · CTI 触发 系统内存 / 外设 代码段 · 数据段 · 堆栈 AXI-AP 可直接读写 典型调试场景: ① 连接目标并识别 CoreSight 组件 → ② 下载程序并设置断点 → ③ 单步/全速运行观察变量 → ④ 采集 ETM/ITM 跟踪 → ⑤ 分析时序与异常路径 工程价值:非侵入观察、可重复自动化、覆盖中断/多核/实时场景,显著缩短定位疑难缺陷的时间。

典型调试场景与工程价值

理解三层结构之后,可以把日常调试工作映射到这条链路上。最常见的场景是“连接目标并识别 CoreSight 组件”:TRACE32 通过 JTAG 复位 TAP、扫描 IDCODE,读取 ROM Table,枚举出 DAP、AP、ETM、ITM 等组件。如果这一步失败,通常不是 TRACE32 软件问题,而是 JTAG 信号完整性、目标供电、复位状态或时钟配置问题。此时应先用示波器检查 TCK/TMS/TDI/TDO 波形,确认目标芯片的调试接口未被禁用(例如某些 SoC 的 eFuse 会关闭 JTAG)。

第二个场景是“下载与断点调试”。TRACE32 通过 AXI-AP 把 ELF 镜像写入目标内存,通过 APB-AP 配置断点单元,然后让 CPU 从入口点运行。当程序命中硬件断点时,CPU 进入调试状态,TRACE32 读取 PC、寄存器组和栈回溯,在源码窗口高亮当前行。这个过程的关键参数包括断点类型(硬件/软件)、断点数量限制、以及是否启用半主机(semihosting)输出。

第三个场景是“跟踪与性能分析”。ETM 以指令为单位输出压缩跟踪包,经 ETB 缓存或 TPIU 输出到 TRACE32 PowerTrace。TRACE32 解码后可以重建完整执行流,统计函数耗时、中断延迟、缓存命中率。例如在 Cortex-M7 上,ITM 可以输出 printf 风格的调试信息而不占用 UART;在 Cortex-A53 多核场景中,CTI 可以同步多个核的断点,实现 SMP 调试。这些能力是纯软件日志无法替代的。

学习建议:初学阶段不必急于配置复杂跟踪,先确保 JTAG 连接稳定、能识别 CoreSight ROM Table、能下载并命中断点。这三步是后续所有高级调试的基础。

从工程价值看,JTAG + CoreSight + TRACE32 的组合解决了三个核心问题:可见性——不修改代码就能观察 CPU 内部状态;可控性——可以精确暂停、单步、修改寄存器和内存;可重复性——通过 .cmm 脚本把调试流程自动化,用于回归测试和产线烧录。对于实时系统、多核系统和安全关键系统,这种非侵入式调试往往是唯一可行的定位手段。

需要特别注意的是,JTAG 只是众多物理接口之一。现代 SoC 越来越多地使用 SWD(Serial Wire Debug)以节省引脚,但 SWD 在协议层仍然通过 DAP 访问 CoreSight,TRACE32 对两者的操作模型基本一致。理解“接口—DAP—AP—组件”这条访问路径,比记住某一种接口的引脚定义更重要。