在嵌入式開(kāi)發(fā)中,調(diào)試永遠(yuǎn)是最痛苦的環(huán)節(jié)。你是否曾經(jīng)為了定位一個(gè)卡頓、死機(jī)、優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題而疲憊不堪?你是否希望能實(shí)時(shí)觀察系統(tǒng)的運(yùn)行細(xì)節(jié),比如任務(wù)切換、時(shí)間片分配、ISR 響應(yīng)時(shí)間?
SystemView 解決了哪些痛點(diǎn)?
傳統(tǒng)日志靠串口輸出,信息有限、時(shí)序混亂,遇到高頻中斷或多任務(wù)調(diào)度就無(wú)能為力。而 SystemView 是 SEGGER 出品的實(shí)時(shí)跟蹤分析工具,它解決了:
任務(wù)調(diào)度不可見(jiàn)?→ 一目了然!
中斷響應(yīng)太慢?→ 毫秒級(jí)分析!
性能瓶頸難以定位?→ 函數(shù)級(jí)耗時(shí)統(tǒng)計(jì)!
系統(tǒng)卡住沒(méi)信息?→ 最后一幀也能還原現(xiàn)場(chǎng)!
SystemView 幫你把 RTOS 從“黑盒”變成“透視玻璃”。
SystemView 的工作原理
SystemView 通過(guò)以下幾個(gè)步驟實(shí)現(xiàn)對(duì)嵌入式系統(tǒng)的實(shí)時(shí)監(jiān)控:
鉤子函數(shù)植入在 RTOS 中植入鉤子函數(shù),實(shí)時(shí)捕獲任務(wù)切換、中斷入口和退出等關(guān)鍵事件。
事件寫(xiě)入 RTT 緩沖區(qū)捕獲的事件數(shù)據(jù)被寫(xiě)入 MCU 內(nèi)部的 RTT(Real-Time Transfer)緩沖區(qū),這是一個(gè)高效的環(huán)形數(shù)據(jù)區(qū)。
數(shù)據(jù)通過(guò)調(diào)試接口傳輸利用 MCU 的調(diào)試接口(如 SWD),RTT 緩沖區(qū)的數(shù)據(jù)被高速傳輸?shù)?a target="_blank">開(kāi)發(fā)者的 PC 端。
PC 端實(shí)時(shí)解析與顯示SystemView PC 工具接收數(shù)據(jù),實(shí)時(shí)解析任務(wù)執(zhí)行順序、時(shí)間關(guān)系及內(nèi)核對(duì)象狀態(tài),并以圖形化界面展示。
實(shí)現(xiàn)低延遲與高可靠監(jiān)控這種設(shè)計(jì)保證了系統(tǒng)狀態(tài)的實(shí)時(shí)反映,方便開(kāi)發(fā)者快速定位和分析問(wèn)題。
SystemView 能做什么?
SystemView 是一個(gè)可以在線調(diào)試嵌入式系統(tǒng)的工具,它能分析系統(tǒng)中哪些中斷、任務(wù)被執(zhí)行了,以及它們的執(zhí)行順序和時(shí)間關(guān)系。同時(shí),它還能記錄系統(tǒng)中各種內(nèi)核對(duì)象(如信號(hào)量、互斥量、事件、消息隊(duì)列等)的持有和釋放時(shí)間點(diǎn),這對(duì)于調(diào)試復(fù)雜的多線程系統(tǒng)非常有效。
SystemView 能夠?qū)崿F(xiàn):
實(shí)時(shí)任務(wù)切換跟蹤
中斷進(jìn)出時(shí)序圖
CPU 占用率統(tǒng)計(jì)
用戶(hù)自定義事件插樁
時(shí)間軸回放與數(shù)據(jù)保存
支持多種主流 RTOS(RT-Thread / FreeRTOS / embOS 等)
盡管 SystemView 提供了強(qiáng)大的系統(tǒng)分析能力,但其在實(shí)際部署中的門(mén)檻仍不容忽視。
傳統(tǒng)上,SystemView 依賴(lài)于 SEGGER 提供的 J-Link 仿真器來(lái)實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)采集和傳輸。這種方案在功能上確實(shí)成熟穩(wěn)定,但對(duì)許多開(kāi)發(fā)者來(lái)說(shuō),也帶來(lái)了一些不小的使用負(fù)擔(dān):
正版 J-Link 的成本相對(duì)較高,盜版J-Link總是容易報(bào)錯(cuò);
同時(shí),J-Link 本身并非為 SystemView 單獨(dú)設(shè)計(jì),在多功能疊加的實(shí)際工程中,調(diào)試、下載、串口通信往往需要額外配合其他工具才能完成。
如何降低 SystemView 的使用門(mén)檻?
其實(shí),SystemView 并不強(qiáng)制要求使用 J-Link——它還提供了一個(gè) UART 模式接口,用于在不具備 SWO 或 Trace 能力的芯片上進(jìn)行數(shù)據(jù)交互。這個(gè) UART 模式的通信協(xié)議是公開(kāi)的,允許通過(guò)串口發(fā)送命令、讀取 RTT 緩沖區(qū),從而實(shí)現(xiàn) SystemView 的核心功能。
那么問(wèn)題來(lái)了:
既然 SystemView 可以用 UART 傳輸數(shù)據(jù),那能不能把這些串口數(shù)據(jù),轉(zhuǎn)發(fā)到 SWD 上的 RTT 通道,從而間接實(shí)現(xiàn)和 MCU 的數(shù)據(jù)交互?
剛好,我制作的多功能工具M(jìn)icroLink 原本就具備RTT 通信的能力,因此可以順勢(shì)在此基礎(chǔ)上拓展,實(shí)現(xiàn)對(duì) SystemView UART 協(xié)議的兼容與轉(zhuǎn)發(fā)。
簡(jiǎn)單來(lái)說(shuō):
SystemView PC 工具選擇UART 模式進(jìn)行通信,通過(guò)虛擬串口向 MicroLink 發(fā)送特定格式的數(shù)據(jù);
MicroLink 內(nèi)部固件識(shí)別并適配 SystemView 的 UART 協(xié)議,對(duì)數(shù)據(jù)包進(jìn)行解析;
MicroLink 將接收到的指令映射為對(duì)目標(biāo) MCU 內(nèi)存的讀寫(xiě)操作,通過(guò)SWD 接口實(shí)現(xiàn)真實(shí)的數(shù)據(jù)訪問(wèn);
MCU 中運(yùn)行的SystemView 嵌入式端程序將運(yùn)行數(shù)據(jù)(任務(wù)調(diào)度、事件、ISR 等)寫(xiě)入 RTT UpBuffer;
MicroLink從 RTT Buffer 中讀取數(shù)據(jù),再通過(guò)串口返回給 SystemView PC 工具;
最終,SystemView 實(shí)時(shí)顯示系統(tǒng)運(yùn)行過(guò)程,形成完整的數(shù)據(jù)回環(huán)。
從此你無(wú)需再專(zhuān)門(mén)購(gòu)買(mǎi)昂貴的正版 J-Link,無(wú)需額外接線,也無(wú)需修改一行代碼。只要插上 MicroLink,打開(kāi) SystemView,選擇 UART 模式,點(diǎn)擊 Start,一切就緒。
MicroLink是一個(gè)在傳統(tǒng) DAPLink 的基礎(chǔ)上進(jìn)行了全面升級(jí),集成了在線仿真器、USB 轉(zhuǎn)串口、脫機(jī)下載器、RTT 通信、SystemView 支持、拖拽燒錄以及用戶(hù)可編程自動(dòng)化工具等多個(gè)功能于一體的“一站式”的調(diào)試與開(kāi)發(fā)工具。
為了感謝大家的關(guān)注和支持,我準(zhǔn)備了一波 MicroLink 抽獎(jiǎng)活動(dòng),歡迎參與贏取這款開(kāi)發(fā)好幫手!
也可以通過(guò)下方鏈接直接購(gòu)買(mǎi),立即提升開(kāi)發(fā)效率:
https://item.taobao.com/item.htm?ft=t&id=895964393739
劃到文章末尾,獲取 MicroLink 開(kāi)源資料,加入技術(shù)交流群,與更多開(kāi)發(fā)者一起探索嵌入式開(kāi)發(fā)的無(wú)限可能。
SystemView 移植與使用步驟
SystemView 包含兩個(gè)部分:
PC 端程序:由 SEGGER 提供的 SystemView 工具,可收集并可視化展示嵌入式系統(tǒng)運(yùn)行時(shí)的行為,包括任務(wù)調(diào)度、中斷響應(yīng)、系統(tǒng)事件等。支持實(shí)時(shí)顯示和數(shù)據(jù)保存以供離線分析。
嵌入式端程序:需要集成到 MCU 工程中,負(fù)責(zé)記錄運(yùn)行信息并通過(guò)RTT(Real-Time Transfer)模塊實(shí)時(shí)發(fā)送到 PC。
嵌入式端程序移植步驟
只需要利用 RT-Thread 推出的 Env 工具 使能 SystemView 軟件包,并對(duì)其進(jìn)行簡(jiǎn)單的配置,就能完成 SystemView 的嵌入式端程序的配置。
以STM32 BSP stm32f103-onenet-nbiot為例,內(nèi)核版本5.2.0,MicroLink固件版本V2.3.1及以上。
步驟一:在 Env 工具中進(jìn)入 menuconfig 圖形化配置工具
打開(kāi) Env 工具,使用命令cd D:rt-threadbspstm32切換到 RT-Thread 源碼 BSP 根目錄下的 stm32f103-onenet-nbiot 目錄,然后輸入命令menuconfig配置工程。
利用上下鍵選中 RT-Thread online packages,按回車(chē)鍵進(jìn)入下級(jí)菜單,在 tools packages 中打開(kāi) SystemView 。
步驟二:配置SystemView
Version選擇latest最新版本,其他選項(xiàng)不需要配置。
menuconfig 配置選項(xiàng)說(shuō)明:
參數(shù) | 描述 |
---|---|
App name | 應(yīng)用程序的名字 |
Device name | 設(shè)備所用內(nèi)核 |
Timestap freq | 時(shí)間戳頻率 (0 表示使用系統(tǒng)默認(rèn)頻率) |
cpu freq | cpu頻率(0 表示使用系統(tǒng)默認(rèn)頻率) |
RAM base | RAM基地址 默認(rèn)值:0x2000 0000 |
Event ID offset | 事件ID的偏移 默認(rèn)值:32 |
Using the Cortex-M cycle ... | 使用系統(tǒng)頻率作為時(shí)間戳 |
System description 0-2 | 系統(tǒng)描述符 "I#num=name, ..." num 是中斷標(biāo)號(hào), name 是中斷名稱(chēng) |
步驟三:打開(kāi)內(nèi)核鉤子函數(shù)
利用上下鍵選中 RT-Thread Kernel,按回車(chē)鍵進(jìn)入下級(jí)菜單,打開(kāi) Enable hook list。
配置好選項(xiàng)之后,按 ESC 返回,退出并保存配置,這樣 SystemView 軟件包的使能和相關(guān)配置就完成了。
后面我們以一個(gè)具體的 demo 來(lái)講解 SystemView 工具的使用。
添加示例代碼
在文件 main.c 中添加以下代碼,然后在 main 函數(shù)中調(diào)用 demo 初始化函數(shù)demo_init();運(yùn)行 demo。
/* * 程序清單:systemview 演示代碼 * * 這個(gè)例子中將創(chuàng)建一個(gè)動(dòng)態(tài)信號(hào)量(初始值為0)及兩個(gè)動(dòng)態(tài)線程,在這個(gè)兩個(gè)動(dòng)態(tài)線程中 * 線程2將試圖采用永遠(yuǎn)等待方式去持有信號(hào)量,持有成功之后發(fā)送運(yùn)行標(biāo)志。 * 線程1將先發(fā)送正在運(yùn)行標(biāo)志,然后釋放一次信號(hào)量,因線程2的優(yōu)先級(jí)較高,線程2持有到信號(hào)量將線程1搶斷。 * 然后線程2發(fā)送運(yùn)行標(biāo)志之后,獲取不到信號(hào)量,被掛起,線程1繼續(xù)運(yùn)行 */ #defineTHREAD_PRIORITY 25 #defineTHREAD_STACK_SIZE 512 #defineTHREAD_TIMESLICE 5 /* 指向信號(hào)量的指針 */ rt_sem_tsem_food; /* 線程1入口 */ voidthread1_entry(void* parameter) { while(1) { /* 線程1第一次運(yùn)行 */ rt_kprintf("thread1 is run!n"); /* 釋放一次信號(hào)量 */ rt_sem_release(sem_food); /* 線程1第二次運(yùn)行 */ rt_kprintf("thread1 run again!n"); /* 線程1延時(shí)1秒 */ rt_thread_delay(RT_TICK_PER_SECOND); } } /* 線程2入口 */ voidthread2_entry(void* parameter) { while(1) { /* 試圖持有信號(hào)量,并永遠(yuǎn)等待直到持有到信號(hào)量 */ rt_sem_take(sem_food, RT_WAITING_FOREVER); /* 線程2正在運(yùn)行 */ rt_kprintf("thread2 is run!n"); } } /* DEMO初始化函數(shù) */ voiddemo_init(void) { /* 指向線程控制塊的指針 */ rt_thread_tthread1_id, thread2_id; /* 創(chuàng)建一個(gè)信號(hào)量,初始值是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; } /* 創(chuàng)建線程1 */ thread1_id = rt_thread_create("thread1", thread1_entry, RT_NULL,/* 線程入口是thread1_entry, 參數(shù)RT_NULL */ THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if(thread1_id != RT_NULL) rt_thread_startup(thread1_id); /* 創(chuàng)建線程2 */ thread2_id = rt_thread_create("thread2", thread2_entry, RT_NULL,/* 線程入口是thread2_entry, 參數(shù)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 添加系統(tǒng)描述文件
首先找到開(kāi)發(fā)板目錄下的 packages 目錄,然后在 packages 目錄下找到 segger_debug-xxx 目錄,在這個(gè)目錄里面有一個(gè) SystemView_Description 文件夾,RT-Thread 系統(tǒng)的描述文件就在里面,具體的目錄結(jié)構(gòu)如下所示:
bsp\你自己的開(kāi)發(fā)板\packages\segger_debug-xxx\SystemView_Description\SYSVIEW_RT-Thread.txt
將這個(gè)文件復(fù)制到 SystemView 工具安裝目錄下的 Description 目錄下,這樣 SystemView 就可以識(shí)別出 RT-Thread 系統(tǒng)了。
步驟三:連接MicroLink,啟動(dòng)SystemView 功能
使用串口助手工具連接MicroLink提供的虛擬串口,并發(fā)送SystemView.start(0x20000000,1024,1)指令,來(lái)啟動(dòng)MicroLink的SystemView 功能模塊。
SystemView.start(0x20000000,1024,1)
0x20000000:搜索RTT控制塊的起始地址;
1024:搜尋范圍大小;
1:?jiǎn)?dòng)RTT的通道。
如上圖所示提示Find SEGGER RTT addr 0x200002ec,說(shuō)明已成功啟動(dòng)SystemView 功能,然后關(guān)閉串口。
如果提示no find _SEGGER_RTT addr,可以打開(kāi)map文件,搜索_SEGGER_RTT 變量的地址,如下圖所示_SEGGER_RTT 地址為0X200002ec,然后將命令替換為SystemView.start(0X200002ec,1024,1)
步驟四:配置設(shè)備信息,開(kāi)始錄制
雙擊打開(kāi) SystemView PC端程序,點(diǎn)擊Taget
選擇UART連接模式
COM口選擇剛才配置MicroLink啟動(dòng)SystemView 功能的端口號(hào),由于MicroLink的虛擬串口使用的是USB CDC模式,所以不需要配置波特率,保持默認(rèn)就行。
點(diǎn)擊OK,啟動(dòng)開(kāi)始錄制按鈕,SystemView 就開(kāi)始實(shí)時(shí)錄制系統(tǒng)信息了。
步驟五:結(jié)束錄制,分析系統(tǒng)
點(diǎn)擊結(jié)束錄制按鈕,結(jié)束錄制。將鼠標(biāo)放置到時(shí)間軸窗口里,利用滾輪將事件放大到適合分析的大小
利用 SystemView 工具我們可以看出來(lái),系統(tǒng)的運(yùn)行確實(shí)如我們?cè)O(shè)想的那樣,線程1先開(kāi)始運(yùn)行,然后在釋放信號(hào)量之后被線程2搶斷。然后線程2運(yùn)行,之后因獲取不到信號(hào)量被掛起,線程1繼續(xù)運(yùn)行。從上面的事件列表還可以看到每個(gè)線程獲取或釋放信號(hào)量的具體時(shí)間。
在這次 demo 中,我們可以總結(jié)出系統(tǒng)整體:
線程切換有序、無(wú)異常延遲;
CPU 主要處于空閑狀態(tài),說(shuō)明整體系統(tǒng)負(fù)載非常低;
所有事件、切換、運(yùn)行時(shí)間都精確呈現(xiàn)。
常見(jiàn)問(wèn)題答疑(FAQ)
問(wèn)題 | 解答 |
---|---|
1. 使用 SystemView 會(huì)不會(huì)影響系統(tǒng)性能? | 幾乎不會(huì)。SystemView 使用 SEGGER 的 RTT 技術(shù)通過(guò) SWD 讀取內(nèi)存中的 trace 數(shù)據(jù),速度快、占用少。傳輸數(shù)據(jù)時(shí)采用memcpy拷貝到緩沖區(qū),不會(huì)頻繁打斷 CPU,數(shù)據(jù)上傳過(guò)程不會(huì)顯著占用總線帶寬,性能影響可以忽略。 |
2. RTT 緩沖區(qū)滿了會(huì)不會(huì)丟數(shù)據(jù)? | 會(huì)。若上位機(jī)沒(méi)有及時(shí)讀取 RTT 緩沖區(qū),舊數(shù)據(jù)可能被新數(shù)據(jù)覆蓋,造成 trace 丟失。建議增大緩沖區(qū)、確保持續(xù)連接并避免暫停采集。 |
3. SystemView 支持哪些 RTOS? | 官方支持 embOS、FreeRTOS、RT-Thread、CMSIS-RTOS 等主流內(nèi)核,也支持通過(guò)接口適配層(SEGGER_SYSVIEW.c/h)接入自定義 RTOS。 |
4. SystemView 能用于裸機(jī)程序嗎? | 可以,但功能受限。裸機(jī)無(wú)任務(wù)調(diào)度,只能記錄中斷或自定義打點(diǎn),無(wú)法進(jìn)行任務(wù)運(yùn)行時(shí)間分析、調(diào)度分析等 RTOS 專(zhuān)屬功能。 |
5. 可以在正式發(fā)布版本中保留 SystemView 嗎? | 不建議。雖然開(kāi)銷(xiāo)小,但 trace 功能占用 RAM/ROM 空間,也可能帶來(lái)信息泄漏風(fēng)險(xiǎn)。推薦僅在開(kāi)發(fā)調(diào)試階段啟用,可用#ifdef DEBUG控制。 |
6. SystemView 支持事后分析模式嗎? | 支持。除了實(shí)時(shí)分析外,SystemView 也支持“事后分析”模式:程序運(yùn)行時(shí)將 trace 數(shù)據(jù)保存到目標(biāo)板上的RAM 中,之后通過(guò) MicroLink 讀取 trace 緩沖區(qū)內(nèi)容進(jìn)行回放分析,適合定位偶發(fā)問(wèn)題或無(wú)法在線連接場(chǎng)景。 |
審核編輯 黃宇
-
RTOS
+關(guān)注
關(guān)注
24文章
851瀏覽量
121186 -
可視化
+關(guān)注
關(guān)注
1文章
1264瀏覽量
21868
發(fā)布評(píng)論請(qǐng)先 登錄
如何在Eclipse ThreadX RTOS中集成SystemView
請(qǐng)問(wèn)freertos可視化調(diào)試中打印任務(wù)信息是不是只可以打印一次?
可視化MES系統(tǒng)軟件
可視化電子看板系統(tǒng)的崗位需求
TensorFlow TensorBoard可視化數(shù)據(jù)流圖
三維可視化的應(yīng)用和優(yōu)勢(shì)
SystemView如何在RT-Thread上對(duì)系統(tǒng)進(jìn)行調(diào)試分析?
淺談基于RTOS系統(tǒng)開(kāi)發(fā)調(diào)試的難題
基于VSCode的嵌入式開(kāi)發(fā)的可視化代碼調(diào)試方法分享
如何在Ubuntu下實(shí)現(xiàn)可視化代碼跟蹤調(diào)試
如何調(diào)試嵌入式代碼?
如何在項(xiàng)目中使用RTOS分析工具SystemView?
使用樹(shù)莓派Pico開(kāi)發(fā)板制作實(shí)時(shí)音頻光譜圖可視化器

評(píng)論