Zephyr tracing 系统--3 使用 Percepio View 跟踪 Zephyr
在 2021 年的时候用 Zephyr tracing 系统–1 简介 和 Zephyr tracing 系统–2 配置和调用框架 两篇文章介绍过 Zephyr tracing 系统的基本原理和配置。当时 Percepio 还只有收费软件,就没有继续写如何使用 Trace 系统,时隔 3 年 Percepio 为 Zephyr 提供了免费的 Percepio View 工具,本文就介绍如何使用 Percepio View 工具跟踪 Zephyr。
Percepio View 链接到标题
Percepio 是 Zephyr 的活跃成员,贡献并持续维护 Zephyr 中的 TraceRecorder 库,该库可帮助开发者观察用 Zephyr RTOS 的实时性。最近其将 Percepio View 作为免费工具提供给 Zephyr 社区,以帮助开发者构建更好的实时应用程序。相对于 Percepio Tracealyzer,Percepio View 功能更为有限,只提供了功能只有 Trace View/Event log/CPU load/Use Event show 4 项功能,其中 CPU load 和 Use Event show 功能需要免费注册后才能使用。
更多 Percepio 跟踪工具产品的对比参看 对比链接
下载 & 安装 链接到标题
Percepio View 的下载链接为:https://traceviewer.io/get-view/,目前有 Windows 和 Linux 的版本。我使用的是 Ubuntu,因此本文以 Linux 介绍说明。
Linux 有 standalone 和 requires Mono 两个版本,建议直接下载 standalone 版本。具体链接是:https://download.tracealyzer.io/PercepioViewForZephyr-4.10.3-linux-standalone-x86-64.tgz
下载完后安装步骤如下:
- 解压到指定目录
tar -zxvf PercepioViewForZephyr-4.10.3-linux-standalone-x86-64.tgz -C ~/portable
- 进入目录安装证书,这步非常重要,不执行会导致之后序列号无法激活
cd ~/portable/PercepioViewForZephyr-4.10.3/
sudo ./cert-sync cacerts_from_mozilla.pem
- 运行 执行下面命令就可以运行 Percepio View
./launch-tz.sh
看到界面如下:
- 注册 Percepio view 注册是免费的,注册后才有 CPU Load Graph 和 User event 功能。第一次启动 Percepio view 会给出注册的链接,如果没有可以访问 https://traceviewer.io/register-view/?target=zephyr 进行注册,注册成功后会将注册码发送到你的邮箱,在 Percepio View 中选择 Help->Enter License Details,弹出的对话框中输入注册码。激活注册码时如果提示下面错误:
可能是没有添加证书(参考前面第 2 步)或是 443 端口被禁用(可能性小)
Zephyr 使用 TraceRecorder 链接到标题
Zephyr 中通过 TraceRecorder 来抓取 RTOS 运行的 Trace 数据,Percepio View 通过这些 Trace 数据就可以分析 RTOS 的运行状态。
配置 链接到标题
Percepio View 只支持快照分析不支持流式实时分析,因此在 Zephyr 中增加下面配置就可以了
CONFIG_TRACING=y
CONFIG_PERCEPIO_TRACERECORDER=y
CONFIG_PERCEPIO_TRC_CFG_STREAM_PORT_RINGBUFFER=y
CONFIG_PERCEPIO_TRC_CFG_STREAM_PORT_RINGBUFFER_SIZE=204800
其中CONFIG_PERCEPIO_TRC_CFG_STREAM_PORT_RINGBUFFER_SIZE
是设置 Trace 数据的 ringbuffer 大小,默认情况下写满了会盖掉久数据继续写,大小根据实际硬件的内存情况进行调整。
数据抓取 链接到标题
Zephyr 中 TraceRecorder 使用RecorderDataPtr
指向 ringbuffer 结构体struct TraceRingBuffer
, Percepio View 获得这个结构体的数据就获取了所有 trace 的数据。Zephyr 中可以通过很多方法将这个结构体的数据 dump 出来。用得最多的是 gdb 和 j-link。本文基于 esp32-c3 的 gdb dump 进行说明。
esp32-c3 jtag/gdb 链接到标题
esp32-c3 内部自带一个 jtag, 外部通过引脚直接连接到 USB 口就可以使用该 Jtag.
- 连接 esp32-c3 jtag 到电脑,按下表进行连线
- GPIO18 - D-
- GPIO19 - D+
- 5V - VCC
- GND - GND
-
安装 openocd
Zephyr 中的 openocd 不能支持 esp32-c3,需要使用 espressif 自己发布的,在 https://github.com/espressif/openocd-esp32/releases 下载,解压缩到/home/frank/portable/openocd-esp32/
-
启动 openocd
export PATH=/home/frank/portable/openocd-esp32/bin:$PATH
openocd -f board/esp32c3-builtin.cfg
启动成功后会看见下面的信息
Open On-Chip Debugger v0.12.0-esp32-20250422 (2025-04-22-13:02)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselecting 'jtag'
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 (84:F7:03:A6:F0:60)
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 40000 kHz
Info : JTAG tap: esp32c3.tap0 tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : [esp32c3] datacount=2 progbufsize=16
Info : [esp32c3] Examined RISC-V core; found 1 harts
Info : [esp32c3] XLEN=32, misa=0x40101104
Info : [esp32c3] Examination succeed
Info : [esp32c3] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
- 编译和启动 gdb
Zephyr SDK 中集成了 gdb,因此不用特别的去安装启动 gdb,编译后通过 debug 命令后直接连接启动
west build -b esp32c3_devkitc zephyr/samples/synchronization/
west debug
如果正常启动 gdb 可以看到如下信息
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/frank/work/zpro/zephyrproject/build/zephyr/zephyr.elf...
Remote debugging using :3333
0x40000000 in ?? ()
Register cache flushed.
JTAG tap: esp32c3.tap0 tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
[esp32c3] Reset cause (3) - (Software core reset)
Hardware assisted breakpoint 1 at 0x420000be: file /home/frank/work/zpro/zephyrproject/build/zephyr/include/generated/zephyr/syscalls/kernel.h, line 84.
(gdb)
dump trace 数据 链接到标题
在 gdb 中执行c
命令让系统运行一段时间后,通过 ctrl+c 暂停运行,在 gdb 中执行下面命令将RecorderDataPtr
指向的 ring buffer 数据 dump 到 trace.bin 中
dump binary value trace.bin *RecorderDataPtr
dump 时 gdb 可能会提示下面错误:
value of type `RecorderData’ requires 207596 bytes, which is more than max-value-size
这是因为 gdb 默认max-value-size
为 64K,需要修改max-value-size
比 RecorderData 大,可以执行下面命令解决
set max-value-size sizeof(*RecorderDataPtr)
Percepio View 分析数据 链接到标题
通过 File->Open 打开 trace.bin 文件,可以加载 trace 数据并显示
但要能完全显示正确还需要一些配置。
配置 链接到标题
当直接打开 trace.bin 文件时,Percepio View 会提示:
这是因为 Percepio View 需要 syscalls.xml 文件,该文件在 Zephyr 的build
构建目录下,需要通过 File->Settings->Define File Path 添加 Zephyr 构建目录的路径
Snapshot 链接到标题
从前面的步骤我们知道,要抓取数据时需要通过 gdb,每次通过命令行并不是很方便。在 Percepio View 中提供 Snapshot 界面,在配置 gdb 的启动参数后,这样就可以直接通过 Snapshot 界面抓取数据,并自动更新分析界面。
配置 GDB Snapshot 链接到标题
Percepio View 只是提供了 gdb 的调用界面,实际 gdb 还是要用户自己配置的。在 File->Settings->GDB Settings 中配置 gdb 的启动参数
- Path to GDB: 是交叉工具链的 gdb,esp32c3 是 risc-v 内核,可以选择 Zephyr SDK 提供的:/home/frank/work/zpro/tools/zephyr-sdk-0.16.8/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-gdb
- Path to Image: 是 gdb 要分析的 elf 文件,选择 Zephyr 的最终构建结果:/home/frank/work/zpro/zephyrproject/build/zephyr/zephyr.elf
- Commands to initialize: 是 gdb 启动时要执行的命令:
target remote 127.0.0.1:3333
连接到 device 的 gdbserver 上set max-value-size sizeof(*RecorderDataPtr)
修改最大 dump size 避免 dump 失败
- Commands to take snapshot: 这是 snap 的 gdb 命令,也就是 dump 数据时要执行的命令
抓取数据 链接到标题
通过 Trace->Open Snapshot Tool 打开 Snap 的界面,Snapshot Engine 选择 GDB,然后点击 Read Snapshot 按钮,就会执行 gdb 命令抓取数据并更新界面。
如果执行成功 Last Result 将提示执行成功和时间,Last Snapshot 将提示 snap 文件的保存位置,同时 Percepio view 也会更新分析刚抓到的数据。
分析 链接到标题
Percepio View 的功能比较简单,基本上手就会,这里做基本介绍
Trace View 链接到标题
Trace View 显示线程执行、中断处理程序、内核 API 调用和自定义用户事件日志的图形时间线。通过该功能可以观察线程是否按按预期运行,也可以查看线程调度优先级是否合适。
上图中一种颜色的色块代表一个线程,点装块表示线程就绪,实心的块状代表线程运行。点击线程的块状图就会展现出该线程执行时发生的事件。同时在 Selection Details 窗口看到该线程当前占用 cpu 的时间和优先级:
CPU Load Graph 链接到标题
显示每个线程和中断处理程序使用的相对 CPU 时间,以及总的 CPU 使用情况。找到高 CPU 负载的热点,以便优化可以带来最大的性能提升。
上图中 thread_a 和 thread_b 有瞬间的高 CPU Loading 状态,如果应用程序出现偶尔卡顿,就可以去这两个线程找原因进行优化。
Event Show 链接到标题
显示已记录的事件列表,包括内核事件和用户事件。易于搜索和筛选。在 Trace 中双击事件,Event 窗口的对应事件将被高亮,反之亦然。
总结 链接到标题
简单的总结在 Zephyr 上使用 Percepio View 的感受:
- Percepio View 虽然免费,但功能有限,适合用来查看内核对象之间的工作关系,也可以用于分析 Zephyr 系统的负载。
- 只要 Zephyr 的板子支持 gdb 就可以使用 Percepio View,但不是开箱即用,要填一些坑(本文已描述)
- 目前试过 Zephyr 上 ARM/RISC-V 体系结构下 TraceRecorder 都使用正常,Xtensa 体系结构下 TraceRecorder 会导致线程切换失败
参考 链接到标题
https://traceviewer.io/getting-started-zephyr-view/
https://www.zephyrproject.org/tracing-zephyr-applications-with-percepio-view/