CoreSight 追踪架构:ETM/ITM 源、funnel、TMC 与 TPIU 导出
更新时间:2026-09-19。前置:JTAG 边界扫描、RISC-V 调试模块。普通调试靠「停住看现场」,CoreSight 的**追踪(trace)**是在 CPU 继续高速运行时,把执行路径/数据/软件事件实时编码成一条流送出,用于找偶发实时问题。
本文要回答的问题
- trace 和普通断点调试有什么本质不同?
- ETM/ITM 等追踪源产生什么,funnel/TMC/TPIU 怎么汇聚导出?
- trace 流最终怎么离开芯片(探头/SWO/片上缓存)?
- 带宽、时钟和缓冲溢出会带来哪些坑?
一、CoreSight 的两大部分
- 调试(debug):halt、单步、读写寄存器/内存——侵入式,对应 ARM 的 DAP(Debug Access Port)经 SWD/JTAG 访问(类比 RISC-V Debug Module、JTAG TAP)。
- 追踪(trace):CPU 不停,硬件实时输出「发生了什么」的压缩流——非侵入,这是本文重点。
二、追踪源(trace sources)
| 源 | 追踪内容 |
|---|---|
| ETM(Embedded Trace Macrocell)/ PTM | 指令执行流(分支/地址),可配数据追踪;压缩率高,靠重建还原完整执行路径 |
| ITM(Instrumentation Trace Macrocell) | 软件主动 printf 风格的激励字(写 ITM 寄存器即输出)、时间戳、异常事件 |
| DWT(Data Watchpoint and Trace) | 数据观察点事件、周期计数、异常时序,可喂给 ITM |
| 其他 | PMU 事件、STM(系统跟踪,多主控/软件统一激励)、片上总线 trace |
ETM 并不逐字节导出每条指令(带宽不够),主要导出分支流和上下文,调试器结合 ELF 静态信息重建指令轨迹;数据追踪/地址范围可按需开。
三、汇聚、缓存与导出(CoreSight 互联)
bash
ETM(core0) ─┐
ETM(core1) ─┤
ITM ────────┼─► funnel(漏斗: 多源合并成一条 ATB 流,带 ID)
STM/PMU ────┘ │
┌──────┴───────┐
▼ ▼
TMC/ETB(片上缓冲) replicator(可复制到多目的)
│ │
▼ ▼
TPIU ── trace 探头(多 trace data 引脚)─► 逻辑分析仪/调试器
(或 SWO: 单线 ITM/少量 trace,经 SWV)- funnel:把多个 trace 源合并成一条流,给每个源的包加 ATB ID,接收端据此区分来源。
- ATB(AMBA Trace Bus):CoreSight 内部追踪总线(与 AXI 不同),带 ID 与流控。
- replicator:把同一流复制到多个目的(如同时送片上缓冲和外部探头)。
- TMC(Trace Memory Controller)/ETB(Trace Buffer):把 trace 流写进片上 SRAM(ETB/ETF)或连续内存(ETR),无外部探头也能事后读;或做成 ETS 做 FIFO 缓冲。
- TPIU(Trace Port Interface Unit):把流格式化后从 trace 引脚导出,可配并行 trace port(1~n 位、双沿)或经 **SWO(Single Wire Output,单线,常跑 NRZ/UART 或 Manchester)**导出 ITM/DWT,成本低但带宽小。
- 时间戳(timestamp):全局计数器给包打时间,保证多核/多源事件可排序。
四、访问与发现
- 调试器经 DAP(SW-DP 两根线 SWCLK/SWDIO,或 JTAG-DP 5 线)访问调试 AP(AHB-AP/APB-AP),进而读写 CoreSight 的内存映射寄存器和 trace 缓冲(类比 RISC-V DMI)。
- CoreSight 有标准的 ROM Table(发现表):调试器扫描 ROM table 自动发现芯片里有哪些 CoreSight 组件及基址,再逐个使能。
- 使能链通常:解锁锁定寄存器(Lock Access)→ 配 funnel 选源 → 配 TPIU/SWO 波特率与格式、或配 TMC 目标内存 → 开 ITM/ETM → 开 trace 主控,结束后停并 flush。
五、带宽与实时性(trace 的核心约束)
- CPU 执行速度远超单个 trace 引脚导出能力。ETM 靠只发分支+高度压缩降低平均带宽,但紧密分支/中断密集时瞬时流量超端口速率,会发生 overflow(丢 trace),缓冲(FIFO/ETB)只能吸收短时突发。
- 对策:加宽并行 trace port、提高 trace 时钟、缩小追踪范围(只追特定地址/条件)、用片上大缓冲 TMC-ETR 写 DDR、或降低 CPU 时钟。
- trace 时钟(TRACECLK)与内核时钟、SWO 参考时钟必须匹配,调试器才能正确解码;SWO 波特率必须在两端一致(类似 UART 波特率)。
- trace 对实时性影响很小(非侵入),但使能数据 trace/大量 ITM 仍有轻微开销和功耗。
六、安全与常见坑
- 带宽不够 overflow:窄端口/SWO 跑密集追踪丢包,重建不完整;用宽端口/缓冲/缩小范围。
- SWO 时钟/波特率错:参考时钟与调试器配置不一致,乱码;需按实际 core clock 分频。
- trace 时钟未供/被门控:低功耗或未开 TRACECLK 时无输出(见 时钟控制器、低功耗)。
- 只使能源不通路:开了 ITM/ETM 但 funnel/TPIU/TMC 没配,看不到数据。
- funnel 源 ID 冲突/未选:多源 ID 配错,解码串流。
- 忘记解锁/ROM table:组件有锁定寄存器,未写 unlock 配置无效。
- ETB 缓冲被覆盖:缓冲满后 wrap 覆盖早期数据,需及时读或配足够大。
- ETR 内存/cache 一致性:TMC 写内存要配到合适地址并注意 CPU cache 一致性(见 DMA 与 cache)。
- 时间戳未使能:多核/多源事件无法排序。
- 调试口安全:trace 可读出完整执行路径和数据,量产必须关闭或安全认证(见 安全启动、总线防火墙、JTAG 锁定)。
- 把 printf 当 ITM 却走 UART:ITM 输出经 SWO,不是普通串口;调试器要用 SWV 视图。
- 引脚复用冲突:trace/SWO 脚被配成 GPIO(见 PinMux)。
相关与延伸
底层 TAP/边界扫描见 JTAG;RISC-V 对应调试见 Debug Module;SWO 串行本质见 UART 波特率;追踪写内存一致性见 DMA 与 cache。
总结
ARM CoreSight 把「非侵入追踪」建成一条流水线:ETM/PTM 输出压缩的分支执行流、ITM 接收软件 printf 式激励字、DWT 输出数据观察点和周期事件,多源经 funnel 用 ATB ID 合并、replicator 复制,再由 TMC/ETB/ETR 缓存到片上 SRAM 或内存、或经 TPIU 的并行 trace port 与单线 SWO 导出给调试器,全局时间戳保证多源排序;调试器本身通过 DAP(SWD/JTAG)扫描 ROM Table 发现并解锁各组件后逐段使能——由于内核速率远高于导出速率,紧密分支下必须靠 ETM 压缩、加宽端口和片上缓冲对抗 overflow,并保证 trace/SWO 时钟一致,量产时务必锁定追踪口以防止执行路径和数据被读出。