目录
集成 ESP-IDF V4.4 和 ESP-IDF V4.3¶
参考资料
https://percepio.com/getstarted/latest/html/esp-idf.html#code-modifications
引言
Tracealyzer:解决程序调度问题的利器
在操作系统或嵌入式系统开发过程中,调试实时调度问题往往极具挑战性。传统的调试方法(如printf打印)不仅效率低下,还可能因引入额外延迟而干扰系统行为,导致难以捕捉真实的运行时问题。
传统调试方法的局限性
printf或其他基于日志的调试手段存在以下缺陷:
- 性能开销大:频繁的I/O操作会显著拖慢程序执行速度,影响调度时序的真实性。
- 实时性不足:无法捕获高频率事件(如上下文切换、中断触发),且可能遗漏关键时间窗口。
- 干扰系统行为:调试代码本身可能改变任务调度顺序,掩盖原有问题。
Tracealyzer的优势
Tracealyzer作为专业的可视化追踪工具,通过以下方式提升调试效率:
- 非侵入式采集:直接读取操作系统内核或RTOS的追踪数据,避免对目标系统造成性能干扰。
- 时间精确性:支持微秒级事件记录,精准呈现任务调度、中断和资源争用的时间线。
- 交互式分析:通过时间轴、甘特图和统计视图,直观定位阻塞、优先级反转等复杂问题。
典型应用场景
- 实时系统中的任务调度异常分析
- 多线程环境下的死锁或资源竞争诊断
- 中断延迟和响应时间的性能优化
通过Tracealyzer,开发者能够摆脱低效的日志调试,快速锁定根因并验证修复方案。
在ESP32S3上带有USB-CDC/JTAG外设,能极大方面调试,不需要外接JTAG调试器了,只需要接上USB即可
安装Tracealyzer软件
首先我们先安装Tracealyzer软件
下载安装包
注意:安装软件仅供学习使用,请支持正版软件。 下载链接
我这里安装的是4.8.1版本最高支持ESP-IDF 5.2环境
访问Percepio官方网站或授权代理商页面,获取最新版Tracealyzer安装包。确保下载版本与操作系统兼容(Windows/Linux)。
运行安装程序
双击打开Tracealyzer-4.8.1-windows64.exe,弹出用户账户控制,点击是




使用Tracealyzer.exe, Tracealyzer.exe.config替换安装目录Tracealyzer 4下的文件
打开TracealyzerKeyfileMaker.exe,点击Generate!生成license文件
运行Tracealyzer,指定刚生成的license文件




然后点接受

安装esp-idf插件
然后是在vscode中安装esp-idf插件
打开vscode搜索插件,直接安装就好了,安装好后左侧会有esp的图标

安装esp-idf框架
再来是安装esp-idf的框架,选择用离线安装的方式比较方便,选则5.2.6版本,这里可以装多个版本在电脑上,选不同目录安装即可,vscode的esp-idf插件能够自己扫描出来
安装包下载地址:https://dl.espressif.cn/dl/esp-idf/

下载完成后,直接双击运行,根据程序的指引,安装到自己想要的目录下就可以了




等待安装完成即可,然后在重启vscode,选择扫描计算机中的包,就能识别到了
点击对应的进行选择

新建tracealyzer 测试工程
好了准备工作就绪,下面开始新建一个工程,然后把tracealyzer的库包含配置到其中进行编译
新建工程
vscode中按F1,在编辑框中输入example projects选我框选的,进行新建工程,然后选个i2s_es8311工程,或者你随意选个工程也行

添加tracealyzer库路径
可以然后选保存工程的地方,保存后,打开工程左侧就能看到这些文件,我们选择cmakelists.txt文件进行编辑

添加这句,
set(EXTRA_COMPONENT_DIRS "D:/Program Files/tracealyzer/Tracealyzer 4/ESP-IDF_FreeRTOS/TraceRecorder/kernelports/ESP-IDF_FreeRTOS")
将trancealyzer包含到工程中来,当然这个路径是根据你安装的trancealyzer路径来的。
也可以运行Tracealyzer 并选择 Help -> ESP-IDF FreeRTOS Trace Recorder,在安装目录中找到 Trace Recorder ESP-IDF 组件,自动就会打开所在目录,然后根据你的目录改改上面的目录就好了

所需的 ESP-IDF 代码修改¶
根据您使用的 esp-idf 版本,需要对 ESP-IDF 代码库进行一些修改。请参阅以下部分,了解与您的 ESP-IDF 版本相对应的相应说明。由于我用的是5.2.6版本,直接看esp-idf V5.0的部分就好了。其他版本参考后续的说明。
集成 ESP-IDF V5.0¶
以下部分介绍 Percepio Trancealyzer与 ESP-IDF V5.0 的集成。
-
打开位于 ESP-IDF 的 components/freertos/FreeRTOS-Kernel/include/freertos 目录下的 FreeRTOS.h。 我的路径是(D:\Espressif5.2.6\frameworks\esp-idf-v5.2.6\components\freertos\FreeRTOS-Kernel\include\freertos),请实际根据自己的路径进行打开
-
之后,添加以下代码:
#include freertos/FreeRTOSConfig.h#ifdef CONFIG_PERCEPIO_TRACERECORDER_ENABLED #include <trcRecorder.h> #endif
我实际插入的代码段

集成 ESP-IDF V4.4 和 ESP-IDF V4.3¶
以下部分介绍了 Percepio 跟踪记录器与 ESP-IDF V4.4 和 ESP-IDF V4.3 的集成。
-
打开位于 ESP-IDF 的“components/esp_system”目录中的 startup.c 并找到 。
esp_newlib_time_init() -
在上述函数之后,添加以下代码:
#if CONFIG_PERCEPIO_TRACERECORDER_ENABLED xTraceInitialize(); #endif /*CONFIG_PERCEPIO_TRACERECORDER_ENABLED*/ -
在同一文件 (startup.c) 中,导航到
#if CONFIG_APPTRACE_ENABLE -
之后,添加以下代码块
assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!");#if CONFIG_PERCEPIO_TRACERECORDER_ENABLED #if CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START == 1 xTraceEnable(TRC_START); #elif CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START_AWAIT_HOST == 1 xTraceEnable(TRC_START_AWAIT_HOST); #elif CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START_FROM_HOST == 1 xTraceEnable(TRC_START_FROM_HOST); #else xTraceInitialize(); #endif #endif /*CONFIG_PERCEPIO_TRACERECORDER_ENABLED*/ -
打开位于 ESP-IDF 的 components/freertos/include/freertos 目录下的 FreeRTOS.h。
-
之后,添加以下代码:
#include freertos/FreeRTOSConfig.h#ifdef CONFIG_PERCEPIO_TRACERECORDER_ENABLED #include <trcRecorder.h> #endif
集成 ESP-IDF V4.2¶
以下部分介绍 Percepio 跟踪记录器与 ESP-IDF V4.2 的集成。
-
打开位于 components/esp32s2(对于 esp32s2)或 components/esp32(对于 esp32)中的 cpu_start.c。
-
导航到 。
void start_cpu0_default(void) -
在上述函数中,在 之后添加以下代码:
intr_matrix_clear()#if CONFIG_PERCEPIO_TRACERECORDER_ENABLED xTraceInitialize(); #endif /*CONFIG_PERCEPIO_TRACERECORDER_ENABLED*/ -
仍在函数 (start_cpu0_default) 中,在 之后添加以下代码:
assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!");#if CONFIG_PERCEPIO_TRACERECORDER_ENABLED #if CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START == 1 xTraceEnable(TRC_START); #elif CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START_AWAIT_HOST == 1 xTraceEnable(TRC_START_AWAIT_HOST); #elif CONFIG_PERCEPIO_RECORDER_CFG_START_MODE_START_FROM_HOST == 1 xTraceEnable(TRC_START_FROM_HOST); #else xTraceInitialize(); #endif #endif /*CONFIG_PERCEPIO_TRACERECORDER_ENABLED*/ -
打开组件/freertos/include/freertos/FreeRTOS.h
-
之后,添加:
#include "freertos/FreeRTOSConfig.h"#ifdef CONFIG_PERCEPIO_TRACERECORDER_ENABLED #include <trcRecorder.h> #endif
配置SDK设置
然后在vscode点击1编译构建工程,编译好后,点2进行sdk配置

打开后,左侧找到components config 的 Application Level Tracing 然后data destination1选JTAG data destination2 选usb_cdc

然后选择左侧的percepio trace recorder,勾选tracealyzer tracing enable
recorder start mode选择为start form host
然后点击保存,再次进行编译

或者用命令idf.py menuconfig进行配置
-
在 ESP IDF 项目目录中打开一个终端并运行
idf.py menuconfig -
导航到 components config->Application Level Tracing
-
如果您使用的是 ESP-IDF V4.2,请为数据目标选择跟踪内存选项。
-
如果您使用的是 ESP-IDF V4.3、V4.4 或 V5.0,请为数据目标选择 JTAG 选项。
-
-
导航回主菜单并转到 Percepio Trace Recorder
-
选中 Tracealyzer Tracing Enable 选项
-
然后进行编译
编译报错
这里如果你用的esp-idf 5.2.6版本,编译会报错
D:/Program Files/tracealyzer/Tracealyzer 4/ESP-IDF_FreeRTOS/TraceRecorder/kernelports/ESP-IDF_FreeRTOS/include/trcKernelPort.h:673:26: error: 'pxCurrentTCB' undeclared (first use in this function); did you mean 'pxCurrentTCBs'?
673 | xTraceTaskSwitch(pxCurrentTCB[xPortGetCoreID()], pxCurrentTCB[xPortGetCoreID()]->uxPriority)
解决方法:只需要定位到这个目录的文件位置,然后将里面的pxCurrentTCB都改为pxCurrentTCBs然后重新编译就能解决问题了。
修改工程例子
到此我们的工程已经编译成功了,当然为了能测试任务调度,我们得写几个运行的任务跑起来。在
i2s_es8311_example.c文件中,的最下方,将app_main()函数替换成如下代码
static void led1_task(void *args)
{
while (1) {
ESP_LOGE(TAG, "task-1\n");
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
static void led2_task(void *args)
{
while (1) {
ESP_LOGE(TAG, "task-2\n");
vTaskDelay(250 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
void app_main(void)
{
xTaskCreate(led1_task, "led1_task", 4096, NULL, 5, NULL);
xTaskCreate(led2_task, "led2_task", 4096, NULL, 2, NULL);
}
然后再次编译烧录即可。
FREERTOS调准备
Tracealyzer适配esp32s3设置
下面开始讲如何在ESP32S3中用tracealyzer进行调试
双击运行安装好的tracealyzer应用

打开后如图

在 Tracealyzer 中,打开设置,导航到 PSF-Streaming Settings,然后选择 Target Connection: GDB


GDB设置
-
导航到 GDB 设置。
-
将 Path to GDB 设置为乐鑫 (xtensa-esp32S3-elf-gdb.exe) 提供的 GDB 可执行文件。这里我的地址是(D:\Espressif5.2.6\tools\xtensa-esp-elf-gdb\16.2_20250324\xtensa-esp-elf-gdb\bin\xtensa-esp32s3-elf-gdb.exe),实际根据你自己的地址来改改
-
将 Path to Image 设置为项目的 .elf 文件。这里是你的工程路径下的build中的文件,我的地址是(D:\mdocument\esp-idf-code\tracefreertostest_es8311task\i2s_es8311\build\i2s-es8311-example.elf),实际根据你自己的地址来改改
-
配置Commands to initialize,如下所示:
target remote localhost:3333 !tz wait 1000 set mem inaccessible-by-default off flushregs set remote hardware-watchpoint-limit 2 set remote hardware-breakpoint-limit 2
-
配置Commands to start stream。我配置的是1情况
-
如果您已将 Percepio Trace Recorder->Recorder 启动模式配置为从主机启动,请输入以下内容:
mon esp apptrace start "file://$(TZ_OUT)" 0 -1 -1 0 0 mon resume
-
如果您已将 Percepio Trace Recorder->Recorder 启动模式配置为启动,请输入以下内容:
mon reset halt mon esp apptrace start "file://$(TZ_OUT)" 0 -1 -1 0 0 mon resume
-
-
配置Commands to end stream,如下所示:
mon esp apptrace stop
-
设置Trace data is received by GDB writes to output specified by $(TZ_OUT)。
-
然后点击 apply 以应用设置即可

好了这里都设置好了,接下来我们就能进行采集了,插上你的usb,esp32s3的usb是GPIO19、20找有引出usb接口的开发板即可。
在这之前还得运行openocd让esp32s3进入调试模式
参考esp32s3的官方文档:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-guides/jtag-debugging/index.html
配置 ESP32-S3 目标板
我们在vscode中选择esp-idf终端

运行 OpenOCD
然后运行命令:
openocd -f board/esp32s3-builtin.cfg
上述命令中 -f 选项后跟的配置文件专用于 ESP32-S3。基于具体使用的硬件,你可能需要选择不同的配置文件,具体内容请参阅 根据目标芯片配置 OpenOCD。
例如,对于带有用于 JTAG 连接的 FT2232H 或 FT232H 芯片的定制板,或带有 ESP-Prog 的定制板,可使用 board/esp32c3-ftdi.cfg。
现在应该可以看到类似如下输出(此日志来自 ESP32-S3):
PS D:\mdocument\esp-idf-code\tracefreertostest_es8311task\i2s_es8311> openocd -f board/esp32s3-builtin.cfg
Open On-Chip Debugger v0.12.0-esp32-20250707 (2025-07-06-17:44)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : esp_usb_jtag: serial (94:A9:90:30:13:90)
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 40000 kHz
Info : JTAG tap: esp32s3.tap0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32s3.tap1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : [esp32s3.cpu0] Examination succeed
Info : [esp32s3.cpu1] Examination succeed
Info : [esp32s3.cpu0] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
Info : [esp32s3.cpu0] Debug controller was reset.
Info : [esp32s3.cpu0] Core was reset.
Info : [esp32s3.cpu1] Debug controller was reset.
Info : [esp32s3.cpu1] Core was reset.
Info : [esp32s3.cpu0] Target halted, PC=0x4037B62A, debug_reason=00000000
Info : [esp32s3.cpu0] Reset cause (1) - (Power on reset)
Info : [esp32s3.cpu1] Target halted, PC=0x4037B62A, debug_reason=00000000
Info : [esp32s3.cpu1] Reset cause (1) - (Power on reset)
Trancealyzer开始进行调试
然后回到Trancealyzer程序,点击record streaming trace

注意:一定要运行openocd后再开始采集才能采集到信息,请保证openocd运行成功
然后我们点击连接和开始会话就开始采集了

采集到的总体界面是这样的,就能进行分析了,任务都在左侧能看到调度时间和cpu占用


1505

被折叠的 条评论
为什么被折叠?



