esp_trace 是 ESP-IDF 全新推出的应用层 Trace(跟踪)组件,它将应用层 Trace 能力拆分为可插拔的 Encoder(编码器)Transport(传输层)。这意味着,开发者在集成新的 Trace 工具时,无需再修改内核代码即可完成接入。

简介

Trace 与 Logging 是两种用途不同的调试工具。

Logging(日志) 用于记录代码主动输出的离散信息;Tracing(跟踪) 持续记录系统运行期间产生的事件,例如 FreeRTOS 任务切换、中断、Queue 操作以及应用层自定义事件。Host 端工具通常会将这些事件还原为时间轴,也可直接通过串口终端查看简单 Trace 输出。当日志无法解释性能或行为异常时,Tracing 往往是更有效的分析手段。

ESP-IDF 新增的 esp_trace 提供统一的运行时管理(启动、停止、Session、锁),并将其余能力拆分为两个可插拔模块:

  • Encoder:定义 Trace 数据格式
  • Transport:负责将 Trace 数据发送到芯片外

两者启动时按名称自动解析,可自由组合,无需修改集成代码。

架构

应用程序统一通过 esp_trace API 工作:

  • esp_trace_write()
  • esp_trace_start()
  • esp_trace_stop()
  • esp_trace_flush()

核心通过 Encoder VTable 与 Transport VTable 分发调用。

在这里插入图片描述

Transport 为可选。如果 Encoder 已可通过 TCP、UDP 或内存输出数据,可在 sdkconfig 中启用:

CONFIG_ESP_TRACE_TRANSPORT_NONE=y

FreeRTOS Hook

FreeRTOS 的 trace*() 宏(如 traceTASK_SWITCHED_INtraceISR_ENTERtraceQUEUE_SEND)在编译期解析,因此不能经过 Encoder VTable。

启用外部 Trace 库后,FreeRTOSConfig.h 会包含 esp_trace_freertos_impl.h,开发者需在其中完成各类 trace*() 宏到 Hook 实现的映射。

可扩展能力

目前,esp_trace 提供了一种正式可用的 Encoder,以及一个用于参考的示例 Encoder。

SEGGER SystemView

乐鑫提供了 esp_sysview Managed Component,可直接集成 SEGGER SystemView

对于需要功能完善的 Host 端可视化 Trace 工具的开发者,这是目前官方推荐的方案。
在这里插入图片描述

示例 Encoder

官方示例还提供了一个轻量级参考 Encoder。

它会将每一个 FreeRTOS 事件输出为一行纯文本,因此无需专用的 Host 端解析工具,只需使用任意串口终端即可实时查看 Trace 输出。

esp_trace 采用开放式架构,开发者可以基于统一的扩展接口实现自己的 Encoder 或 Transport,并以 Managed Component 的形式发布。

未来,乐鑫还计划支持 CTF (Common Trace Format) Encoder,进一步丰富 esp_trace 的生态。

对于应用程序而言,无论底层使用哪种 Encoder 或 Transport,调用方式始终保持一致,仅需在 Kconfig 中切换对应配置即可完成替换。

集成示例解析

官方示例位于 examples/system/esp_trace,这是一个最小可运行工程,用于演示如何完成 Encoder 与 FreeRTOS Hook 的集成。

示例主要包含以下内容:

  • 注册一个外部 Encoder;
  • 在不同 CPU Core 上运行 Producer Task 与 Consumer Task;
  • 通过 USB-Serial-JTAG 输出每一个 FreeRTOS 事件对应的 Trace 信息。

在这里插入图片描述
输出内容中,每行开头的数字表示距离上一条事件发生所经过的时间,单位为 μs

整个过程无需 Host 端解码器或其他专用工具,只需使用任意串口终端连接 USB-Serial-JTAG 接口,即可实时查看 Trace 输出。

示例中的 app_main.c 仅使用 esp_trace 提供的通用 API。

程序首先调用 esp_trace_start() 开启 Trace,随后运行一段时间的任务,再依次调用 esp_trace_stop()esp_trace_flush() 结束并输出 Trace 数据。

整个应用程序无需直接引用具体的 Encoder 或 Transport,实现之间的绑定关系均由配置自动完成。这正是 esp_trace 引入抽象层的目的——将应用逻辑与具体实现解耦,使不同的 Encoder 和 Transport 能够灵活替换,而无需修改应用代码。

该示例同时也是开发者将新的 Trace Recorder 集成到 ESP-IDF 时的推荐起点。

关于示例的完整目录结构、各文件的作用、CMake 配置方法,以及集成过程中需要注意的常见问题,均可参考示例 README。相比在本文中重复介绍,这也是官方推荐的参考资料。

总结

esp_trace 让第三方 Trace 工具无需修改 ESP-IDF 内核即可完成集成。开发者仅需实现 Encoder 与 Transport 两个接口,即可封装为独立 Managed Component。

目前推荐使用 SystemView,官方示例提供最小参考实现,未来还将支持 CTF Encoder。

延伸阅读

如果希望进一步了解 esp_trace,可以参考以下资料:

  • components/esp_trace:了解 esp_trace 的整体架构,以及 Encoder VTable 和 Transport VTable 的接口说明。
  • examples/system/esp_trace:最小集成示例。如果计划开发自己的 Encoder,建议从该示例开始。
  • examples/system/sysview_tracing:演示如何通过 esp_sysview Encoder Adapter 完成基于 SystemView 的完整 Trace 流程。
  • Application Tracing API Guide:介绍 ESP-IDF 的应用层 Trace 体系,以及 esp_trace 在整个 Tracing 框架中的定位。

如果基于 esp_trace 开发了新的功能或扩展,欢迎与乐鑫分享成果,我们也期待看到更多基于 esp_trace 构建的优秀项目。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐