在调试程序执行路径、函数调用顺序、异常前后现场时,经常会用到TRACE32的trace记录。遇到“TRACE32 trace记录怎么开启TRACE32 trace记录为空怎么排查”,不能只看有没有点【Go】。Trace记录是否有内容,和芯片是否支持trace、TRACE32选择的trace method、缓冲区是否初始化、AutoArm是否开启、触发条件和过滤范围是否设置正确都有关系。简单说,trace不是普通断点窗口,它需要先有“数据来源”,再有“记录配置”,最后才有“显示结果”。
一、TRACE32 trace记录怎么开启
TRACE32 trace记录的开启,一般先从Trace配置窗口或命令脚本开始。常见流程是选择trace method、清空trace buffer、设置记录模式和大小,然后运行目标程序。程序运行时开始记录,程序停止后再查看Trace.List。TRACE32的Trace Tutorial中给出的基础配置流程就是打开Trace Configuration、初始化缓冲区、选择记录模式和设置缓冲区大小。
1、先确认使用哪一种Trace方式
不同芯片和不同TRACE32硬件,使用的trace方式不一样。比如有的工程用Analyzer,有的用Onchip,有的用Arm ETM,有的Cortex-M工程可能用MTB。不能看到菜单里有Trace,就默认所有芯片都能直接录到完整执行流。
(1)如果是外部trace硬件采集,常见会选择Trace.METHOD Analyzer。
(2)如果是片上trace buffer,比如部分Cortex-M的MTB,则要按Onchip思路配置。Cortex-M MTB场景下,TRACE32会把MTB当作片上trace buffer,需要设置Trace.METHOD Onchip,同时还要告诉TRACE32 trace buffer的地址和大小。
2、配置Trace缓冲区和记录模式
基础配置可以从【Trace】→【Configuration】进入,也可以用命令脚本配置。
常用命令大致包括Trace.METHOD Analyzer、Trace.Init、Trace.Mode Fifo、Trace.SIZE 10000000。其中Trace.Init用来清空旧记录,Trace.Mode Fifo表示新记录覆盖旧记录,保留停止前最近一段trace;Stack模式则更偏向保留开始记录后的前面一段内容。
3、运行程序并在停止后查看记录
配置完成后,运行程序,trace通常会随程序执行开始采集。TRACE32的教程中说明,按【Go】开始运行时trace recording会自动开始,按【Break】停止程序后记录停止;AutoArm默认开启时,trace会跟随程序运行和停止自动管理。
记录完成后,可以通过【Trace】→【List】→【Default】查看,也可以输入Trace.List。这里有一个很容易忽略的点:trace结果需要在trace状态为OFF时查看,记录进行中不能正常显示trace数据。TRACE32教程中也明确说明,trace results只能在Trace窗口状态为OFF时显示。
如果你一边运行一边看Trace.List,发现里面没有更新,不一定是没有记录,可能只是当前还在采集中。正确做法是先让程序停住,再打开或刷新Trace.List。
二、TRACE32 trace记录为空怎么排查
Trace.List为空时,不要只反复执行Go和Break。要先看trace状态有没有进入Arm或Analyzing,再看used字段有没有变化,然后再查硬件连接、ETM/TPIU/MTB配置、触发条件和过滤条件。很多空记录不是程序没跑,而是trace采集根本没有被真正打开。
1、先看Trace状态和used字段
最直接的判断方式是打开Trace.state。程序运行前,状态是否进入Arm;程序运行时,used字段是否增加;程序停止后,状态是否回到OFF。这几个信息比Trace.List是否有内容更重要。
如果AutoArm关闭了,就需要手动Arm Analyzer。部分TRACE32目标接口说明中提到,AutoArm开启时analyzer会在用户程序启动时自动arm;如果AutoArm关闭,就要通过【Trace】→【Arm Analyzer】手动开始采集。
如果状态一直是OFF,说明没有真正进入记录。如果状态能Arm,但used一直是0,说明trace源没有数据进来,或者触发、过滤、硬件链路某一环没通。这个时候继续看Trace.List没意义,要回到配置窗口查源头。
2、检查ETM、TPIU或MTB配置是否正确
Arm ETM场景下,除了Trace.state,还要看ETM.state。ETM trace能不能正常工作,取决于芯片内部ETM资源、TPIU输出路径、trace时钟、trace引脚复用和TRACE32采集硬件是否匹配。Arm ETM文档里也说明,可以通过Trace菜单打开ETM设置,或者用ETM.state查看ETM资源和配置。
如果是Cortex-M MTB,则重点不是外部trace引脚,而是片上RAM里的MTB buffer是否配置对。TRACE32需要知道MTB buffer的基地址和大小,否则即使程序运行了,也无法把片上记录解释出来。Cortex-M tracing资料中给出的关键点就是设置buffer地址和Trace.SIZE。
如果trace记录一直为空,可以按这个顺序查:芯片是否支持对应trace类型;TRACE32 trace method是否选对;trace引脚是否被复用成GPIO;TPIU/ETM是否开启;MTB buffer是否真的放在有效RAM区;目标程序有没有把这段RAM又拿去做栈、堆或普通数据区。
3、检查过滤、触发和记录范围
Trace记录为空,还有一种常见原因是过滤条件设置太窄。比如只记录某个地址范围,但程序没有跑进这个范围;设置了触发条件,但触发事件从来没有发生;或者include/exclude区域写错,导致真正执行的代码都被排除掉了。
这类问题排查时,建议先把复杂条件清掉,用最简单的方式录一段全局程序流。如果能录到,再逐步加触发和过滤;如果最简单配置都录不到,再回头查硬件和trace method。
另外也要注意AutoInit。Arm ETM示例中提到,如果Trace.state里的AutoInit为ON,每次程序启动时trace内容都会被清空。这个功能本身很有用,但如果你以为旧记录还会保留,就容易误判“怎么刚才还有,现在又空了”。
三、TRACE32 trace记录使用时要注意什么
Trace记录比普通断点调试更依赖硬件条件。断点调试只要能halt CPU、读寄存器和内存,很多问题就能看;trace则要求目标芯片能输出或保存执行流,TRACE32能接收并解码这些信息。排查时要把它当成一条完整链路,而不是一个窗口功能。
1、先用最小配置验证采集链路
刚开始不要急着设置复杂触发、函数过滤、代码覆盖率或性能统计。建议先用Fifo模式,清空buffer,运行一个确定会执行的函数,然后手动Break,看used字段是否变化,Trace.List是否能显示记录。
只要最小链路打通,后面再加函数范围、触发条件、时间戳、OS上下文或覆盖率统计。这样排查起来更稳,不会把硬件问题、配置问题和分析视图问题混在一起。
2、符号和源码会影响显示效果
Trace记录本质上记录的是执行流或数据访问,想在Trace.List里看到漂亮的函数名、源码行和高级语言视图,还需要正确加载符号文件。Arm ETM示例里也提到,执行脚本后可以用List.auto显示源码,用Trace.List显示trace内容,还可以选择HLL Source Only查看高级语言trace。
如果Trace.List里有地址,但没有函数名,不一定是trace没录到,而可能是ELF没加载、符号版本不对、源码路径丢失,或者当前地址落在没有符号信息的代码段。这个问题要按符号加载排查,不要误判成trace为空。
3、记录为空和记录无法解码要分开看
Trace.List完全没有记录,和有记录但显示undefined、乱序、无法解码,不是同一种问题。前者多半是没有采集到数据;后者可能是trace时钟、阈值、电气连接、端口宽度、解码参数不匹配。
总结
TRACE32 trace记录怎么开启,核心流程是选对trace method,执行Trace初始化,设置Fifo或Stack模式,运行程序,停机后用Trace.List查看。TRACE32 trace记录为空怎么排查,重点看Trace.state状态、used字段、AutoArm、Trace method、ETM/TPIU/MTB配置、buffer地址、触发过滤条件和trace硬件链路。实际调试时,建议先用最小配置录到一段确定会执行的程序流,再逐步增加过滤、触发和分析功能。只要把“是否采集到数据”和“是否正确解码显示”分开判断,trace为空这类问题就不会越查越乱。