0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

实时可视化调试:SystemView 助你掌控RTOS运行态

Rice嵌入式开发技术分享 ? 来源:Rice嵌入式 ? 作者:Rice嵌入式 ? 2025-07-10 10:38 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式开发中,调试永远是最痛苦的环节。你是否曾经为了定位一个卡顿、死机、优先级反转的问题而疲惫不堪?你是否希望能实时观察系统的运行细节,比如任务切换、时间片分配、ISR 响应时间?

SystemView 解决了哪些痛点?

传统日志靠串口输出,信息有限、时序混乱,遇到高频中断或多任务调度就无能为力。而 SystemView 是 SEGGER 出品的实时跟踪分析工具,它解决了:

任务调度不可见?→ 一目了然!

中断响应太慢?→ 毫秒级分析!

性能瓶颈难以定位?→ 函数级耗时统计!

系统卡住没信息?→ 最后一帧也能还原现场!

SystemView 帮你把 RTOS 从“黑盒”变成“透视玻璃”。

SystemView 的工作原理

SystemView 通过以下几个步骤实现对嵌入式系统的实时监控:

钩子函数植入在 RTOS 中植入钩子函数,实时捕获任务切换、中断入口和退出等关键事件。

事件写入 RTT 缓冲区捕获的事件数据被写入 MCU 内部的 RTT(Real-Time Transfer)缓冲区,这是一个高效的环形数据区。

数据通过调试接口传输利用 MCU 的调试接口(如 SWD),RTT 缓冲区的数据被高速传输到开发者的 PC 端。

PC 端实时解析与显示SystemView PC 工具接收数据,实时解析任务执行顺序、时间关系及内核对象状态,并以图形化界面展示。

实现低延迟与高可靠监控这种设计保证了系统状态的实时反映,方便开发者快速定位和分析问题。

SystemView 能做什么?

SystemView 是一个可以在线调试嵌入式系统的工具,它能分析系统中哪些中断、任务被执行了,以及它们的执行顺序和时间关系。同时,它还能记录系统中各种内核对象(如信号量、互斥量、事件、消息队列等)的持有和释放时间点,这对于调试复杂的多线程系统非常有效。

SystemView 能够实现:

实时任务切换跟踪

中断进出时序图

CPU 占用率统计

用户自定义事件插桩

时间轴回放与数据保存

支持多种主流 RTOS(RT-Thread / FreeRTOS / embOS 等)

wKgZPGg-UUaATaqhAAPZipRYOak651.png

尽管 SystemView 提供了强大的系统分析能力,但其在实际部署中的门槛仍不容忽视。

传统上,SystemView 依赖于 SEGGER 提供的 J-Link 仿真器来实现数据的实时采集和传输。这种方案在功能上确实成熟稳定,但对许多开发者来说,也带来了一些不小的使用负担:

正版 J-Link 的成本相对较高,盗版J-Link总是容易报错;

同时,J-Link 本身并非为 SystemView 单独设计,在多功能叠加的实际工程中,调试、下载、串口通信往往需要额外配合其他工具才能完成。

如何降低 SystemView 的使用门槛?

其实,SystemView 并不强制要求使用 J-Link——它还提供了一个 UART 模式接口,用于在不具备 SWO 或 Trace 能力的芯片上进行数据交互。这个 UART 模式的通信协议是公开的,允许通过串口发送命令、读取 RTT 缓冲区,从而实现 SystemView 的核心功能。

那么问题来了:

既然 SystemView 可以用 UART 传输数据,那能不能把这些串口数据,转发到 SWD 上的 RTT 通道,从而间接实现和 MCU 的数据交互?

刚好,我制作的多功能工具MicroLink 原本就具备RTT 通信的能力,因此可以顺势在此基础上拓展,实现对 SystemView UART 协议的兼容与转发。

简单来说:

SystemView PC 工具选择UART 模式进行通信,通过虚拟串口向 MicroLink 发送特定格式的数据;

MicroLink 内部固件识别并适配 SystemView 的 UART 协议,对数据包进行解析;

MicroLink 将接收到的指令映射为对目标 MCU 内存的读写操作,通过SWD 接口实现真实的数据访问;

MCU 中运行的SystemView 嵌入式端程序将运行数据(任务调度、事件、ISR 等)写入 RTT UpBuffer;

MicroLink从 RTT Buffer 中读取数据,再通过串口返回给 SystemView PC 工具

最终,SystemView 实时显示系统运行过程,形成完整的数据回环。

wKgZPGg-UUaAH3FpAABHUV8I6Uo586.jpg

从此你无需再专门购买昂贵的正版 J-Link,无需额外接线,也无需修改一行代码。只要插上 MicroLink,打开 SystemView,选择 UART 模式,点击 Start,一切就绪。

MicroLink是一个在传统 DAPLink 的基础上进行了全面升级,集成了在线仿真USB 转串口脱机下载器RTT 通信SystemView 支持拖拽烧录以及用户可编程自动化工具等多个功能于一体的“一站式”的调试与开发工具。

为了感谢大家的关注和支持,我准备了一波 MicroLink 抽奖活动,欢迎参与赢取这款开发好帮手!

也可以通过下方链接直接购买,立即提升开发效率:

https://item.taobao.com/item.htm?ft=t&id=895964393739

划到文章末尾,获取 MicroLink 开源资料,加入技术交流群,与更多开发者一起探索嵌入式开发的无限可能。

SystemView 移植与使用步骤

SystemView 包含两个部分:

PC 端程序:由 SEGGER 提供的 SystemView 工具,可收集并可视化展示嵌入式系统运行时的行为,包括任务调度、中断响应、系统事件等。支持实时显示和数据保存以供离线分析。

嵌入式端程序:需要集成到 MCU 工程中,负责记录运行信息并通过RTT(Real-Time Transfer)模块实时发送到 PC。

嵌入式端程序移植步骤

只需要利用 RT-Thread 推出的 Env 工具 使能 SystemView 软件包,并对其进行简单的配置,就能完成 SystemView 的嵌入式端程序的配置。

STM32 BSP stm32f103-onenet-nbiot为例,内核版本5.2.0,MicroLink固件版本V2.3.1及以上。

步骤一:在 Env 工具中进入 menuconfig 图形化配置工具

打开 Env 工具,使用命令cd D:rt-threadbspstm32切换到 RT-Thread 源码 BSP 根目录下的 stm32f103-onenet-nbiot 目录,然后输入命令menuconfig配置工程。

利用上下键选中 RT-Thread online packages,按回车键进入下级菜单,在 tools packages 中打开 SystemView 。

wKgZPGg-UUaAS0JaAACoWeoovbg060.jpg

步骤二:配置SystemView

Version选择latest最新版本,其他选项不需要配置。

wKgZPGg-UUaAaxfcAAC6jERKp8g032.jpg

menuconfig 配置选项说明:

参数 描述
App name 应用程序的名字
Device name 设备所用内核
Timestap freq 时间戳频率 (0 表示使用系统默认频率)
cpu freq cpu频率(0 表示使用系统默认频率)
RAM base RAM基地址 默认值:0x2000 0000
Event ID offset 事件ID的偏移 默认值:32
Using the Cortex-M cycle ... 使用系统频率作为时间戳
System description 0-2 系统描述符 "I#num=name, ..." num 是中断标号, name 是中断名称

步骤三:打开内核钩子函数

利用上下键选中 RT-Thread Kernel,按回车键进入下级菜单,打开 Enable hook list。

wKgZPGg-UUaAT1ktAAEQqE2vX6M538.jpg

配置好选项之后,按 ESC 返回,退出并保存配置,这样 SystemView 软件包的使能和相关配置就完成了。

后面我们以一个具体的 demo 来讲解 SystemView 工具的使用。

添加示例代码

在文件 main.c 中添加以下代码,然后在 main 函数中调用 demo 初始化函数demo_init();运行 demo。

/*
* 程序清单:systemview 演示代码
*
* 这个例子中将创建一个动态信号量(初始值为0)及两个动态线程,在这个两个动态线程中
* 线程2将试图采用永远等待方式去持有信号量,持有成功之后发送运行标志。
* 线程1将先发送正在运行标志,然后释放一次信号量,因线程2的优先级较高,线程2持有到信号量将线程1抢断。
* 然后线程2发送运行标志之后,获取不到信号量,被挂起,线程1继续运行
*/
#defineTHREAD_PRIORITY     25
#defineTHREAD_STACK_SIZE    512
#defineTHREAD_TIMESLICE    5
/* 指向信号量的指针 */
rt_sem_tsem_food;
/* 线程1入口 */
voidthread1_entry(void* parameter)
{
 while(1)
  {
   /* 线程1第一次运行 */
    rt_kprintf("thread1 is run!n");
   /* 释放一次信号量 */
    rt_sem_release(sem_food);
   /* 线程1第二次运行 */
    rt_kprintf("thread1 run again!n");
   /* 线程1延时1秒 */
    rt_thread_delay(RT_TICK_PER_SECOND);
  }
}
/* 线程2入口 */
voidthread2_entry(void* parameter)
{
 while(1)
  {
   /* 试图持有信号量,并永远等待直到持有到信号量 */
    rt_sem_take(sem_food, RT_WAITING_FOREVER);
   /* 线程2正在运行 */
    rt_kprintf("thread2 is run!n");
  }
}
/* DEMO初始化函数 */
voiddemo_init(void)
{
 /* 指向线程控制块的指针 */
 rt_thread_tthread1_id, thread2_id;
 /* 创建一个信号量,初始值是0 */
  sem_food = rt_sem_create("sem_food",0, RT_IPC_FLAG_PRIO);
 if(sem_food == RT_NULL)
  {
    rt_kprintf("sem created fail!n");
   return;
  }
 /* 创建线程1 */
  thread1_id = rt_thread_create("thread1",
          thread1_entry, RT_NULL,/* 线程入口是thread1_entry, 参数RT_NULL */
          THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
 if(thread1_id != RT_NULL)
    rt_thread_startup(thread1_id);
 /* 创建线程2 */
  thread2_id = rt_thread_create("thread2",
          thread2_entry, RT_NULL,/* 线程入口是thread2_entry, 参数RT_NULL */
          THREAD_STACK_SIZE, THREAD_PRIORITY -1, THREAD_TIMESLICE);
 if(thread2_id != RT_NULL)
    rt_thread_startup(thread2_id);
}

PC 端SystemView 配置及使用

步骤一:下载 SystemView 分析工具

下载链接:

https://www.segger.com/products/development-tools/systemview/

步骤二:为 RT-Thread 添加系统描述文件

首先找到开发板目录下的 packages 目录,然后在 packages 目录下找到 segger_debug-xxx 目录,在这个目录里面有一个 SystemView_Description 文件夹,RT-Thread 系统的描述文件就在里面,具体的目录结构如下所示:

bsp\你自己的开发板\packages\segger_debug-xxx\SystemView_Description\SYSVIEW_RT-Thread.txt

将这个文件复制到 SystemView 工具安装目录下的 Description 目录下,这样 SystemView 就可以识别出 RT-Thread 系统了。

步骤三:连接MicroLink,启动SystemView 功能

使用串口助手工具连接MicroLink提供的虚拟串口,并发送SystemView.start(0x20000000,1024,1)指令,来启动MicroLink的SystemView 功能模块。

SystemView.start(0x20000000,1024,1)

0x20000000:搜索RTT控制块的起始地址;

1024:搜寻范围大小;

1:启动RTT的通道。

wKgZPGg-UUaAHWRbAAE29Pd1RrE261.jpg

如上图所示提示Find SEGGER RTT addr 0x200002ec,说明已成功启动SystemView 功能,然后关闭串口

如果提示no find _SEGGER_RTT addr,可以打开map文件,搜索_SEGGER_RTT 变量的地址,如下图所示_SEGGER_RTT 地址为0X200002ec,然后将命令替换为SystemView.start(0X200002ec,1024,1)

wKgZPGg-UUeAKhHAAAFgICUxrRo347.jpg

步骤四:配置设备信息,开始录制

双击打开 SystemView PC端程序,点击Taget

wKgZPGg-UUeAWDT4AADgPgr_aq0077.jpg

选择UART连接模式

wKgZPGg-UUeALG2mAAAuV6rley4097.jpg

COM口选择刚才配置MicroLink启动SystemView 功能的端口号,由于MicroLink的虚拟串口使用的是USB CDC模式,所以不需要配置波特率,保持默认就行。

wKgZPGg-UUeAH_8ZAAA_goFWFfI284.jpg

点击OK,启动开始录制按钮,SystemView 就开始实时录制系统信息了。

wKgZPGg-UUeAfGQoAACk4lhoAwQ650.jpg

步骤五:结束录制,分析系统

点击结束录制按钮,结束录制。将鼠标放置到时间轴窗口里,利用滚轮将事件放大到适合分析的大小

wKgZPGg-UUeAHfa1AAGOkIxp8do633.jpg

利用 SystemView 工具我们可以看出来,系统的运行确实如我们设想的那样,线程1先开始运行,然后在释放信号量之后被线程2抢断。然后线程2运行,之后因获取不到信号量被挂起,线程1继续运行。从上面的事件列表还可以看到每个线程获取或释放信号量的具体时间。

在这次 demo 中,我们可以总结出系统整体:

线程切换有序、无异常延迟;

CPU 主要处于空闲状态,说明整体系统负载非常低;

所有事件、切换、运行时间都精确呈现。

常见问题答疑(FAQ)

问题 解答
1. 使用 SystemView 会不会影响系统性能? 几乎不会。SystemView 使用 SEGGER 的 RTT 技术通过 SWD 读取内存中的 trace 数据,速度快、占用少。传输数据时采用memcpy拷贝到缓冲区,不会频繁打断 CPU,数据上传过程不会显著占用总线带宽,性能影响可以忽略。
2. RTT 缓冲区满了会不会丢数据? 会。若上位机没有及时读取 RTT 缓冲区,旧数据可能被新数据覆盖,造成 trace 丢失。建议增大缓冲区、确保持续连接并避免暂停采集。
3. SystemView 支持哪些 RTOS? 官方支持 embOS、FreeRTOS、RT-Thread、CMSIS-RTOS 等主流内核,也支持通过接口适配层(SEGGER_SYSVIEW.c/h)接入自定义 RTOS。
4. SystemView 能用于裸机程序吗? 可以,但功能受限。裸机无任务调度,只能记录中断或自定义打点,无法进行任务运行时间分析、调度分析等 RTOS 专属功能。
5. 可以在正式发布版本中保留 SystemView 吗? 不建议。虽然开销小,但 trace 功能占用 RAM/ROM 空间,也可能带来信息泄漏风险。推荐仅在开发调试阶段启用,可用#ifdef DEBUG控制。
6. SystemView 支持事后分析模式吗? 支持。除了实时分析外,SystemView 也支持“事后分析”模式:程序运行时将 trace 数据保存到目标板上的RAM 中,之后通过 MicroLink 读取 trace 缓冲区内容进行回放分析,适合定位偶发问题或无法在线连接场景。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RTOS
    +关注

    关注

    24

    文章

    851

    浏览量

    121327
  • 可视化
    +关注

    关注

    1

    文章

    1266

    浏览量

    21930
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何在Eclipse ThreadX RTOS中集成SystemView

    SEGGER实时软件分析工具SystemView已经在ThreadX v6.4.2上进行了测试。SystemView从v3.60c版本支持Eclipse ThreadX(Azure RTOS
    的头像 发表于 05-06 17:11 ?787次阅读

    请问freertos可视化调试中打印任务信息是不是只可以打印一次?

    在freertos中,使用可视化调试打印任务消息,但是打印不全,还只能打印一次,使用IAR自带的调试插件看,显示可视化调试任务的堆栈顶全是a
    发表于 05-07 06:16

    可视化MES系统软件

    管理层以图表、图像形式将过程控制数据、质量控制数据、实时更新的数据和历史统计的数据可视化展示,让管理者更直观地管理生产现场。最后,可通过接口管理平台实现与ERP,MES系统软件,PDM,CAPP等系统信息
    发表于 11-30 19:55

    如何把AD中非可视化区域物件移到可视化区域?

    AD中非可视化区域物件怎么移到可视化区域???
    发表于 09-10 05:36

    可视化电子看板系统的岗位需求

    系统 是一个可视化管理的工具,让管理人员更直观的了解实时生产情况,控制了有些工序的生产速度和数量,不是传统的生产得越多越好,使得库存控制在一个能满足客户需求的合理水平,但并不是有些人道听途说的零库存。在
    发表于 10-19 20:07

    Python数据可视化

    Python数据可视化:网易云音乐歌单
    发表于 07-19 08:30

    TensorFlow TensorBoard可视化数据流图

    TensorBoard:接下来,打开浏览器并输入地址 http://localhost:6006/(或运行 TensorBoard 命令后收到的链接)。你会看到类似于图 1 中的图,顶部有很多标签。Graphs(图表)选项卡能将运算图可视化:图 1 运算图
    发表于 07-22 21:26

    三维可视化的应用和优势

    的整体态势。  比如设备在偏僻区域(海下、深山、沙漠、分布全国各地等),可以实现无人检测,无需消耗人力物力进行检测,通过三维数据的分析可以直观的探测出设备状态和产能。  设备运行可视化:根据图像
    发表于 12-02 11:52

    SystemView如何在RT-Thread上对系统进行调试分析?

    本文主要介绍 SystemView可视化分析工具,以及如何在 RT-Thread 上使用它对系统进行调试分析。
    发表于 03-30 07:39

    浅谈基于RTOS系统开发调试的难题

    例,它可以实时记录RTOS运行时的各种系统事件,例如任务的调度,任务与任务之间、任务与中断之间的通信等,以此分析出系统在运行期间的行为,并通过图形或文件
    发表于 04-28 13:28

    基于VSCode的嵌入式开发的可视化代码调试方法分享

    ,经常会遇到问题不是那么明显,不方便通过加打印的方式进行排查的问题,并且加打印排查的方式较为低效,使得调试过程极为痛苦。可视化调试效率一直比命令行调试要方便和快捷很多,而嵌入式开发由于
    发表于 12-14 07:54

    如何在Ubuntu下实现可视化代码跟踪调试

    目录一、在Ubuntu下实现可视化代码跟踪调试1.1 安装VSCode1.2 配置调试和编译文件一、在Ubuntu下实现可视化代码跟踪调试1
    发表于 12-14 07:02

    如何调试嵌入式代码?

    调试的?如何借助SEGGER Ozone 和SystemView 实现可视化实时监测跟踪系统运行详情的?
    发表于 12-17 06:32

    如何在项目中使用RTOS分析工具SystemView

    。因此RTOS应用的实时行为对于开发者而言并不是非常直观的,此时就可以用到SystemView这样的RTOS可视化分析工具来帮助分析应用的实
    发表于 07-05 14:00

    使用树莓派Pico开发板制作实时音频光谱图可视化

    本期教程将会通过使用一块带有外置数字麦克风和 TFT LCD 显示屏的树莓派 Pico 开发板制作一个实时音频光谱图可视化器。有了它,你就可以将你周围环境的实时声音可视化表现出来!下图
    的头像 发表于 10-24 10:49 ?3346次阅读
    使用树莓派Pico开发板制作<b class='flag-5'>实时</b>音频光谱图<b class='flag-5'>可视化</b>器