3. 时序分析的数据基础
做时序分析时,最容易犯的错误是“把不同来源的时间数字直接相减”。TRACE32 里看到的 trace 时间戳、CPU 的时钟周期计数、总线上的传输周期、RTOS 的系统节拍,本质上是四套不同的时间尺度。如果不先厘清它们之间的换算关系,得到的“耗时”可能偏差几倍甚至几十倍。本节先把这几个概念的定义和换算关系讲清楚,再落到 TRACE32 中时间基准设置、时间戳精度校准和跨核时间同步的具体做法。
一、五个时间概念的定义与层级关系
先明确参照系:以下所有“周期”均以 CPU 主时钟为基准,时间戳则以 TRACE32 采集系统的时基为基准,两者通过校准系数关联。
- 时钟周期(Clock Period):CPU 主时钟的倒数。例如主频 600 MHz,时钟周期约 1.667 ns。它是所有周期计数的物理基准。
- 指令周期(Instruction Cycle):一条指令从取指到退休所占的时钟周期数。Cortex-M7 上一条
ADD可能是 1 周期,而一次未命中缓存的LDR可能达到几十周期。它反映的是“执行效率”。 - 总线周期(Bus Cycle):一次总线事务(读/写、单次/突发)占用的时钟周期数。它受等待状态(Wait State)、总线矩阵仲裁、从设备响应速度影响,反映的是“访存代价”。
- 系统节拍(System Tick):RTOS 或调度器的心跳,通常由 SysTick 或定时器产生,周期为 1 ms 或 100 µs。它反映的是“调度粒度”,与 CPU 周期不在同一量级。
- 时间戳(Timestamp):TRACE32 在采集 trace 或采样时给每条记录打上的时间标记,单位可能是 ns、µs 或“时基计数”。它是分析时唯一可直接比较的时间轴。
关键换算关系是:时间戳增量 = 周期数 × 时钟周期 × 校准系数。校准系数用于补偿时基晶振与 CPU 时钟之间的频率偏差,通常接近 1 但不等于 1。
二、TRACE32 中的时间基准设置
TRACE32 的时间基准由 trace 采集硬件(如 CombiProbe、PowerTrace)的时基计数器决定。默认情况下,时基频率与目标 CPU 时钟异步,因此必须显式设置。典型操作如下:
; 设置 trace 时基为 CPU 时钟的 1/4,降低计数器翻转频率
Trace.TIME.Base 150MHz
; 查看当前时基配置
Trace.TIME.Base
; 将时间戳显示单位设为 ns
Trace.TIME.Unit ns
; 打开周期计数与时间戳的联合显示
Trace.List /Time /Cycle
这里 Trace.TIME.Base 150MHz 的含义是:时基计数器每计一个数代表 1/150 MHz ≈ 6.667 ns。选择 1/4 主频是为了在长时间采集时不溢出 32 位计数器。若采集窗口超过 28 秒(2³² × 6.667 ns),就需要启用 64 位时基或分段采集。
三、时间戳精度校准
时间戳精度校准的目标是求出校准系数 K。做法是:在目标代码中放置两个已知周期数的标记点,例如一段执行 1000 次空循环的代码,其理论周期数可通过静态分析或周期精确仿真得到。然后在 TRACE32 中读取两个标记点的时间戳差值,与理论值比较。
示例:假设主频 600 MHz,理论时钟周期 1.667 ns。一段循环理论耗时 12000 周期,即 12000 × 1.667 = 20004 ns。TRACE32 实测时间戳差值为 20040 ns,则:
K = 20040 / 20004 ≈ 1.0018
这个 K 值说明时基实际比标称慢约 0.18%。在后续所有换算中,应使用 实际时间 = 周期数 × 1.667 ns × 1.0018。若忽略 K,在 1 ms 量级的测量中会引入约 1.8 µs 的系统误差,对于分析中断延迟这类微秒级问题已经不可忽略。
四、跨核时间同步
多核系统中,每个核可能有独立的 trace 时基,或共享一个时基但存在采集通道延迟。跨核时间同步要解决两个问题:时基对齐和通道延迟补偿。
TRACE32 提供 Trace.SYNC 命令族用于多核同步。典型流程是:先让所有核运行到同一个同步点(如一个全局变量置位),再触发采集。TRACE32 会记录各通道在该同步点的时间戳,并计算通道间偏移。
; 多核同步配置示例(Cortex-A + Cortex-M 异构)
Trace.SYNC.Master A53_0
Trace.SYNC.Slave M7_0
Trace.SYNC.Offset M7_0 12ns ; 手动补偿已知通道延迟
Trace.SYNC.Calibrate ; 自动校准各通道偏移
Trace.SYNC.STATus ; 查看同步状态与残余偏差
校准后,Trace.SYNC.STATus 会给出各从通道相对主通道的偏移量和残余抖动。残余抖动通常在 1~2 个时基周期以内。若残余偏差超过 10 ns,应检查采集探头连接和时钟走线,而不是继续用软件补偿。
五、从时间戳到瓶颈判断
有了统一的时间轴,就可以把不同来源的事件放在一起比较。例如:一次中断从触发到 ISR 第一条指令执行,时间戳差值为 850 ns;其中总线周期占 320 ns,指令周期占 180 ns,剩余 350 ns 是流水线冲刷和向量取指。这个分解结果直接指向优化方向——如果总线等待占主导,应检查 Flash 等待状态和缓存配置;如果流水线冲刷占主导,应检查中断向量表对齐和分支预测。
下表给出一个示例性的时间分解记录表,用于在分析时逐项填写。表中数值为教学示例,非实测结果。
| 阶段 | 周期数 | 换算时间(K=1.0018) | 占比 |
|---|---|---|---|
| 中断触发到向量取指 | 210 | 350 ns | 41% |
| 总线读取 ISR 首指令 | 192 | 320 ns | 38% |
| 指令执行与流水线填充 | 108 | 180 ns | 21% |
| 合计 | 510 | 850 ns | 100% |
这张表的价值在于:它把“850 ns”这个笼统数字拆成了可归因的三段。没有时间戳校准和跨核同步,这三段根本无法对齐到同一时间轴,也就无法判断哪一段是真正的瓶颈。
最后强调一个操作纪律:每次更换目标板、修改 PLL 配置或调整 trace 时基后,都要重新执行一次校准并记录 K 值。把 K 值、时基频率、采集日期写进分析记录,后续复现和对比才有意义。