在嵌入式开发中,高效调试与性能分析是提升开发效率的关键。Segger 提供的 RTT(实时传输技术)和 SystemView 工具,在 ZephyrOS 环境下可实现无引脚占用的高速日志输出与系统行为可视化分析。本文以 NXP MIMXRT1170-EVK 开发板为例,详解在 ZephyrOS 中使能这两项功能的完整流程,涵盖工程配置、编译烧录、上位机连接,帮助开发者快速掌握调试利器。
资料获取:ZephyrOS中使能Segger RTT和Systemview[RT1170_EVK为例]
1. 核心优势与环境准备
1.1 功能核心价值
- RTT 模式:通过 SWD/JTAG 调试口传输日志,不占用 UART 引脚,传输速度快(远超串口),对系统实时性影响极小,支持双向数据交互;
- SystemView 功能:可视化记录线程切换、中断响应、软件事件等时序信息,生成时间线轨迹,直观分析系统负载与调度瓶颈。
1.2 软硬件环境
- 硬件:NXP MIMXRT1170-EVK 开发板(板载调试器,需刷写 JLink 固件)、USB 连接线;
- 软件:Zephyr SDK、MCUXpresso for VS Code、Segger J-Link Software Pack(含 RTT Viewer)、Segger SystemView;
- 工程基础:Zephyr 官方
hello_world示例工程(基于 Cortex-M7 核心)。
2. RTT 使能:高速日志输出实现
2.1 工程准备与代码优化
(1)导入基础工程
在 MCUXpresso for VS Code 中导入工程:
- 仓库路径:Zephyr 源码目录下
zephyr/samples/hello_world; - 目标板:
NXP MIMXRT1170-EVK CM7(标识符:mimxrt1170_evk@A/mimxrt1176/cm7); - 工程名称:自定义(如
rtt_systemview_demo)。
(2)优化代码(模拟线程调度场景)
修改
main.c,创建两个交替运行的线程,通过信号量同步,便于观察 RTT 输出:#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#define PRIORITY 5
#define STACK_SIZE 1024
#define PERIOD_MS 500
// 定义信号量(用于线程同步)
K_SEM_DEFINE(sem_a, 1, 1);
K_SEM_DEFINE(sem_b, 0, 1);
// 定义线程栈
K_THREAD_STACK_DEFINE(stack_a, STACK_SIZE);
K_THREAD_STACK_DEFINE(stack_b, STACK_SIZE);
// 线程数据结构
static struct k_thread thread_a_data;
static struct k_thread thread_b_data;
// 线程工作函数
static void worker(const char *name, struct k_sem *mine, struct k_sem *other) {
while (1) {
k_sem_take(mine, K_FOREVER); // 获取自身信号量
// 日志输出(后续将路由到 RTT)
printk("[%s] Hello from %s, uptime=%u msn",
name, CONFIG_BOARD, (uint32_t)k_uptime_get_32());
k_busy_wait(100000); // 忙等 100ms(模拟任务执行)
k_msleep(PERIOD_MS); // 睡眠 500ms(触发线程切换)
k_sem_give(other); // 释放对方信号量
}
}
// 线程 A 入口
static void thread_a(void *p1, void *p2, void *p3) {
ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3);
worker("A", &sem_a, &sem_b);
}
// 线程 B 入口
static void thread_b(void *p1, void *p2, void *p3) {
ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3);
worker("B", &sem_b, &sem_a);
}
int main(void) {
// 动态创建线程
k_thread_create(&thread_a_data, stack_a, K_THREAD_STACK_SIZEOF(stack_a),
thread_a, NULL, NULL, NULL, PRIORITY, 0, K_NO_WAIT);
k_thread_name_set(&thread_a_data, "thread_a");
k_thread_create(&thread_b_data, stack_b, K_THREAD_STACK_SIZEOF(stack_b),
thread_b, NULL, NULL, NULL, PRIORITY, 0, K_NO_WAIT);
k_thread_name_set(&thread_b_data, "thread_b");
printk("RTT/SystemView demo start on %sn", CONFIG_BOARD);
return 0;
}
2.2 Zephyr 配置:禁用 UART 并启用 RTT Snippet
(1)修改工程配置文件(prj.conf)
禁用默认 UART 控制台,避免冲突:
CONFIG_UART_CONSOLE=n(2)通过 Snippet 启用 RTT
Zephyr 的 Snippet 机制可快速加载预设配置,RTT 对应的 Snippet 为
rtt-console,编译命令如下:west build -b mimxrt1170_evk@A/mimxrt1176/cm7 {你的工程路径} -S rtt-console -p
- 参数说明:
-S rtt-console启用 RTT 控制台,-p强制重新配置工程。
2.3 获取 RTT 控制块地址
编译完成后,在工程
build/zephyr 目录下找到 zephyr.map 文件,搜索 _SEGGER_RTT,记录其地址(如 0x20000410),后续上位机连接需用到该地址。2.4 烧录与上位机连接
(1)烧录固件
将编译生成的
zephyr.bin 烧录到 RT1170-EVK 开发板(可通过 MCUXpresso for VS Code 直接烧录)。(2)RTT Viewer 连接配置
- 打开 Segger J-Link RTT Viewer;
- 配置连接参数:
- 目标设备:
MIMXRT1176XXXA_M7; - 接口与速率:
SWD、4000kHz; - RTT Control Block 地址:填入
zephyr.map中查到的地址(如0x20000410);
- 目标设备:
- 点击 “OK” 连接,成功后即可在终端看到线程交替输出的日志:
RTT/SystemView demo start on mimxrt1170_evk Booting Zephyr OS build v4.2.0-3273-g9b7d73cf676e [A] Hello from mimxrt1170_evk, uptime=0 ms [B] Hello from mimxrt1170_evk, uptime=600 ms [A] Hello from mimxrt1170_evk, uptime=1201 ms ...
3. SystemView 使能:系统行为可视化分析
3.1 编译配置(启用 SystemView Snippet)
SystemView 对应的 Zephyr Snippet 为
rtt-tracing,需与 RTT Snippet 同时启用,编译命令如下:west build -b mimxrt1170_evk@A/mimxrt1176/cm7 {你的工程路径} -S rtt-tracing -S rtt-console -p
- 说明:
rtt-tracing用于开启 SystemView 所需的跟踪功能,依赖 RTT 传输跟踪数据。
3.2 烧录与 SystemView 连接
- 重新烧录编译生成的固件;
- 打开 Segger SystemView 软件,配置目标设备与连接参数(与 RTT Viewer 一致);
- 点击 “Start” 开始跟踪,系统将记录线程切换、信号量操作、中断事件等时序数据,生成可视化时间线;
- 分析要点:可查看线程运行时长、调度延迟、系统负载分布,快速定位死锁、优先级翻转等问题。
4. 备选方案:纯 KConfig 配置(无需 Snippet)
若需通过 KConfig 直接配置(而非 Snippet),可在 prj.conf 中添加以下配置(从工程 build/zephyr/.config 文件提取):
# 启用 Segger 模块
CONFIG_ZEPHYR_SEGGER_MODULE=y
CONFIG_HAS_SEGGER_RTT=y
CONFIG_USE_SEGGER_RTT=y
# RTT 核心配置
CONFIG_SEGGER_RTT_CUSTOM_LOCKING=y
CONFIG_SEGGER_RTT_CB_ALIGNMENT=16
CONFIG_SEGGER_RTT_MAX_NUM_UP_BUFFERS=3
CONFIG_SEGGER_RTT_MAX_NUM_DOWN_BUFFERS=3
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=1024
CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN=16
CONFIG_SEGGER_RTT_PRINTF_BUFFER_SIZE=64
CONFIG_SEGGER_RTT_MODE_NO_BLOCK_SKIP=y
CONFIG_SEGGER_RTT_SECTION_DTCM=y
CONFIG_SEGGER_RTT_INIT_MODE_STRONG_CHECK=y
配置完成后,直接执行
west build -b xxx {工程路径} -p 即可编译。5. 关键避坑事项
- 调试器固件:RT1170-EVK 板载调试器需刷写 JLink 固件,否则无法识别设备;
- 控制块地址:必须从
zephyr.map中获取实际_SEGGER_RTT地址,不可随意填写; - 依赖关系:SystemView 依赖 RTT 传输数据,需先确保 RTT 正常工作,再启用
rtt-tracing; - 线程配置:示例中线程优先级相同,通过信号量实现交替运行,若优先级不同需调整同步逻辑;
- 速率匹配:SWD 速率建议设为 4000kHz,速率过高可能导致连接不稳定。
ZephyrOS 中启用 Segger RTT 和 SystemView 的核心是 “利用 Snippet 快速配置 + 依赖 RTT 传输通道”:RTT 提供高速日志输出,SystemView 实现系统行为可视化,两者结合可大幅提升嵌入式开发的调试效率。整个流程无需复杂硬件改动,重点在于工程配置与上位机参数匹配,适用于 RT1170 系列及其他 Zephyr 支持的开发板。
阅读全文
245