4. Trace数据采集与配置

Trace 数据采集的本质,是把处理器内部“看不见”的执行流、数据访问流和总线事务流,通过片上跟踪单元(如 ARM CoreSight ETM/PTM、RISC-V Trace Encoder、Intel PT 等)压缩编码后,经专用 Trace 端口或 Aurora/HSSTP 高速串行链路送出,再由 TRACE32 的 Preprocessor 与 Trace 采集卡接收、解压、重建为可分析的时间序列。配置 Trace 的核心矛盾只有一个:在有限的片上缓冲与链路带宽下,尽可能长时间、无丢失地捕获你真正关心的那段行为。因此,指令 Trace、数据 Trace、总线 Trace 的选择,触发条件、过滤窗口与存储深度的设置,本质上都是在“观测范围”与“数据量”之间做权衡。

三类 Trace 的取舍

指令 Trace 记录程序计数器(PC)的流向,包括分支跳转、异常入口、返回地址,是分析函数调用、循环热点、中断抖动的基础。它数据量中等,压缩后通常每几个周期才产生一次信息,适合长时间开启。数据 Trace 记录 load/store 的地址与数据值,能暴露缓存未命中、伪共享、DMA 与 CPU 争抢等内存瓶颈,但数据量极大,往往需要配合地址窗口过滤。总线 Trace 记录 AXI/AHB/ACE 等总线上的读写事务、突发长度与响应,用于定位带宽饱和、仲裁延迟和跨主设备干扰,其数据率最高,通常只在短窗口内开启。

工程上常见的做法是“指令 Trace 常开 + 数据/总线 Trace 条件触发”。例如先用指令 Trace 定位到某个耗时函数,再针对该函数的地址范围开启数据 Trace,观察它访问了哪些 cache line。

Trace 采集链路与配置要素 目标处理器 CPU 核 / 流水线 ETM / Trace Encoder ATB / 片上 Trace 总线 FIFO 缓冲 Trace 端口 Aurora / HSSTP TRACE32 采集硬件 Preprocessor 解压 时间戳对齐 Trace 存储 RAM 溢出 / 丢帧检测 USB / 以太网 TRACE32 PowerView Trace 列表 / 时间线视图 函数耗时 / 覆盖率统计 数据访问 / 总线事务分析 导出 CSV / 报告 关键配置要素与作用 触发条件 Trigger • 地址匹配(函数入口) • 数据值匹配(写 0xDEAD) • 计数器(第 N 次命中) • 外部信号 / 交叉触发 决定“从哪一刻开始记录” 过滤窗口 Filter • 地址范围(函数/模块) • 数据地址窗口 • 特权级 / 安全态 • 时间窗口(周期区间) 决定“记录哪些内容” 存储深度 Depth • 片上 FIFO 大小 • 采集卡 RAM 容量 • 循环缓冲 / 单次填充 • 溢出阈值告警 决定“能记录多久” 链路带宽 Bandwidth • 端口速率(Gbps) • 压缩比(指令/数据) • 突发峰值 vs 平均 • 丢帧计数寄存器 决定“能否不丢数据” 四者相互制约:过滤越严 → 数据越少 → 可延长存储深度或降低带宽压力

触发条件与过滤窗口的配合

触发条件解决“什么时候开始记”,过滤窗口解决“记什么”。两者配合才能把有限的存储深度用在刀刃上。以 ARM CoreSight ETM 为例,典型配置流程如下:

; 1. 使能 ETM 并选择指令 Trace
ETM.ON
ETM.TraceEnable ON

; 2. 设置触发:命中函数 do_fft 入口地址时启动
ETM.Trigger ON
ETM.Trigger.Address 0x80001A40
ETM.Trigger.Mode Entry

; 3. 设置过滤窗口:只记录 0x80001000~0x80002000 范围
ETM.Filter.Address 0x80001000--0x80002000
ETM.Filter.Enable ON

; 4. 设置存储深度与循环模式
Trace.RAMSize 64M
Trace.Mode Circular

; 5. 启动采集
Trace.Start

这里 Trace.Mode Circular 表示循环缓冲:新数据覆盖旧数据,适合“事后回溯”场景——程序跑飞或卡死后停止采集,缓冲区里保留的正是最后一段执行流。若关心的是触发点之后的完整过程,则用 Single 模式,触发后填满即停。

溢出、丢帧与带宽受限的工程处理

Trace 溢出(overflow)通常表现为 TRACE32 提示 “Trace overflow” 或时间线上出现空洞。根因有三类:一是瞬时数据率超过链路带宽,二是片上 FIFO 太小而 CPU 突发产生大量 Trace,三是过滤窗口过宽导致数据量远超预期。处理顺序建议从“减数据”入手,而不是先加硬件。

  • 收窄过滤窗口:把地址范围从整个模块缩小到具体函数,数据 Trace 只保留目标变量的地址窗口。
  • 降低 Trace 类型:先关数据 Trace,只留指令 Trace 确认执行流;确认后再按需开启。
  • 使用触发后延迟:设置 ETM.Trigger.Delay,跳过初始化阶段的大量无关 Trace。
  • 提高链路速率或改用循环缓冲:在硬件支持时提升 Aurora lane 速率,或接受“只保留最后 N 秒”。
  • 检查丢帧计数:读取采集卡的丢帧寄存器,若丢帧集中在某段时间,说明该段存在突发峰值。
注意:循环缓冲模式下,如果 Trace 数据率长期高于链路带宽,覆盖速度会快于写入速度,表现为“缓冲区里只有最近极短一段”。此时应优先降低数据产生率,而不是盲目增大 RAM。

一个可复用的配置检查清单

检查项典型值/操作判断依据
Trace 类型指令 Trace 常开,数据/总线按需数据量是否可接受
触发地址目标函数入口或关键变量地址触发后是否命中预期位置
过滤窗口地址范围 + 特权级Trace 列表中是否混入无关代码
存储模式Circular / Single是否需要保留触发前历史
溢出状态无 overflow 提示时间线是否连续
丢帧计数0 或可接受范围采集卡寄存器读数

实际调试中,建议先用最小配置跑通一次采集,确认 Trace 列表能正确显示函数调用,再逐步加入数据 Trace 和总线 Trace。每次只改一个配置项,观察数据量和溢出状态的变化,这样才能把“Trace 配好了”从感觉变成可验证的结论。