在Amazon FreeRTOS V10中使用运行时统计信息
在MCU on Eclipse網(wǎng)站上看到Erich Styger在8月2日發(fā)的博文,一篇關(guān)于在Amazon FreeRTOS V10中使用運(yùn)行時(shí)統(tǒng)計(jì)信息的文章,本人覺得很有啟發(fā),特將其翻譯過來以備參考。原文網(wǎng)址:https://mcuoneclipse.com/2018/08/02/tutorial-using-runtime-statistics-with-amazon-freertos-v10/
FreeRTOS包含一個(gè)很好的功能,可以向我提供有關(guān)每個(gè)任務(wù)在系統(tǒng)上運(yùn)行的時(shí)間的信息:
FreeRTOS運(yùn)行時(shí)信息
本教程解釋了FreeRTOS運(yùn)行時(shí)統(tǒng)計(jì)功能以及如何打開和使用它。
?軟件和工具
在本文中,我使用以下內(nèi)容:
? MCUXpresso IDE 10.2.1
? FRDM-K64F板
? 來自MCUXpresso SDK 2.4.0的Amazon FreeRTOS V10.0.1
但是當(dāng)然可以使用任何其他工具/ IDE或FreeRTOS版本(FreeRTOS至少應(yīng)該是9.0.0或更高版本)。
使用以下步驟,還可以使用FreeRTOS任務(wù)運(yùn)行時(shí)信息收集來更新現(xiàn)有項(xiàng)目。
?怎么運(yùn)行的
FreeRTOS使用用戶/應(yīng)用程序特定的計(jì)時(shí)器來測量任務(wù)執(zhí)行時(shí)間。為此,RTOS中的每個(gè)任務(wù)描述符都有一個(gè)累積計(jì)數(shù)器,用于添加為該任務(wù)花費(fèi)的計(jì)時(shí)器滴答。當(dāng)任務(wù)獲得CPU時(shí)間時(shí),當(dāng)前計(jì)時(shí)器滴答計(jì)數(shù)被記憶,當(dāng)RTOS切換出該任務(wù)時(shí),則記憶當(dāng)前計(jì)時(shí)器滴答計(jì)數(shù)。然后將對應(yīng)于任務(wù)執(zhí)行時(shí)間的增量時(shí)間添加到任務(wù)執(zhí)行時(shí)間計(jì)數(shù)器。
我需要配置FreeRTOS,并將以下宏設(shè)置為1以執(zhí)行運(yùn)行時(shí)分析:
另外,需要提供以下兩個(gè)宏:
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() portGET_RUN_TIME_COUNTER_VALUE()RTOS使用它來配置運(yùn)行時(shí)計(jì)數(shù)器計(jì)時(shí)器并獲取計(jì)時(shí)器值。
運(yùn)行時(shí)計(jì)數(shù)器在每個(gè)任務(wù)描述符中存儲(chǔ)為32位值,這意味著對于每個(gè)任務(wù),我對系統(tǒng)的RAM要求將增加4個(gè)字節(jié):
FreeRTOS TCB中的ulRunTimeCounter
假設(shè)計(jì)數(shù)器周期為10 kHz(0.1 ms),這意味著變量將在大約5天后溢出。
此外,RTOS在task.c中維護(hù)額外的全局變量:
第一個(gè)變量用于記住任務(wù)切換的時(shí)間,第二個(gè)變量是系統(tǒng)的總運(yùn)行時(shí)間。這是在任務(wù)切換時(shí)發(fā)生的事情(內(nèi)核函數(shù)vTaskSwitchContext):
/* Add the amount of time the task has been running to theaccumulated time so far. The time the task started running wasstored in ulTaskSwitchedInTime. Note that there is no overflowprotection here so count values are only valid until the timeroverflows. The guard against negative values is to protectagainst suspect run time stat counter implementations - whichare provided by the application, not the kernel. */ if( ulTotalRunTime > ulTaskSwitchedInTime ) {pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); } else {mtCOVERAGE_TEST_MARKER(); } ulTaskSwitchedInTime = ulTotalRunTime;通常,周期性定時(shí)器中斷用于計(jì)算執(zhí)行時(shí)間,并且定時(shí)器頻率應(yīng)該是嘀嗒中斷頻率的大約10倍(比如說“Hello”到“奈奎斯特 - 香農(nóng)”采樣定理)。這意味著如果我的滴答中斷是1 kHz,我的運(yùn)行時(shí)分析定時(shí)器頻率應(yīng)該是10 kHz。
運(yùn)行時(shí)統(tǒng)計(jì)信息通常帶有兩個(gè)數(shù)字:
? 絕對(時(shí)間)數(shù)字
? 百分比
下面是一個(gè)文本任務(wù)列表,其中包含右側(cè)的運(yùn)行時(shí)信息:
TCB Static Handle Name State Prio Stack Beg Stack End Size Stack Top Unused Runtime
1 no (0) 0x20000450 Shell Running (1,1) 0x20000440 0x20000060 1000 B 0x200001EC ( 600 B) 392 B 0x00000000 ( <1%)
7 no (0) 0x20001E68 IDLE Ready (0,0) 0x20001E58 0x20001CD0 400 B 0x20001DFC ( 96 B) 312 B 0x00007C35 ( 91%)
2 no (0) 0x20000740 Refl Blocked (4,4) 0x20000730 0x20000510 552 B 0x200006BC ( 120 B) 384 B 0x00000C6E ( 9%)
6 no (0) 0x20001C68 Main Blocked (1,1) 0x20001C58 0x20001A08 600 B 0x20001BDC ( 128 B) 356 B 0x00000000 ( <1%)
3 no (0) 0x20001378 Radio Blocked (3,3) 0x20001368 0x20000F88 1000 B 0x200012F4 ( 120 B) 680 B 0x00000001 ( <1%)
4 no (0) 0x20001658 Sumo Blocked (2,2) 0x20001648 0x20001458 504 B 0x200015C4 ( 136 B) 360 B 0x00000000 ( <1%)
5 no (0) 0x20001948 Drive Blocked (3,3) 0x20001938 0x20001748 504 B 0x200018B4 ( 136 B) 264 B 0x00000000 ( <1%)
絕對數(shù)字是運(yùn)行時(shí)間計(jì)時(shí)器滴答數(shù)(TCB中的ulRunTimeCounter)以及此計(jì)數(shù)器相對于總運(yùn)行時(shí)間的百分比(task.c中的ulTotalRunTime)。
對于IDLE任務(wù),它顯示了這一點(diǎn):
TCB Static Handle Name State Prio Stack Beg Stack End Size Stack Top Unused Runtime
7 no (0) 0x20001E68 IDLE Ready (0,0) 0x20001E58 0x20001CD0 400 B 0x20001DFC ( 96 B) 312 B 0x00007C35 ( 91%)
0x7C35是定時(shí)器計(jì)數(shù)器(在本例中使用0.1 ms定時(shí)器,因此它意味著IDLE任務(wù)運(yùn)行約3秒(0x7C35 / 10 => 3179 ms)并使用91%的運(yùn)行時(shí)間。
問題可能是:中斷花費(fèi)的時(shí)間是多少?答案是RTOS不知道中斷,它只知道任務(wù)使用了多少運(yùn)行時(shí)間計(jì)時(shí)器。或者換句話說:FreeRTOS運(yùn)行時(shí)計(jì)數(shù)器顯示的運(yùn)行時(shí)* includes*中斷的時(shí)間。
?教程:使用FreeRTOS進(jìn)行運(yùn)行時(shí)分析
在下一節(jié)中,我將展示如何使用FreeRTOS啟用運(yùn)行時(shí)分析。基本步驟是:
? 創(chuàng)建一個(gè)新項(xiàng)目(如果尚未存在)
? 更新FreeRTOSConfig.h
? 初始化和配置計(jì)時(shí)器
? 添加鉤子/回調(diào)到應(yīng)用程序
1、創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)基于你的目標(biāo)板的項(xiàng)目:
項(xiàng)目創(chuàng)建的目標(biāo)板
確保包含F(xiàn)reeRTOS:
項(xiàng)目的FreeRTOS選項(xiàng)
2、添加FreeRTOS任務(wù)
接下來添加一個(gè)任務(wù),例如:
在main()內(nèi)部,創(chuàng)建一個(gè)任務(wù)并啟動(dòng)調(diào)度程序:
/* create task */if (xTaskCreate(MyTask, "MyTask", 500/sizeof(StackType_t), NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {for(;;){} /* error */}vTaskStartScheduler(); /* start RTOS */for(;;) {/* should not get here */}
添加FreeRTOS任務(wù)
構(gòu)建和調(diào)試該項(xiàng)目,只是為了確保一切正常。
調(diào)試FreeRTOS任務(wù)
要在Debug視圖中顯示FreeRTOS線程,請參閱https://mcuoneclipse.com/2018/06/29/show-freertos-threads-in-eclipse-debug-view-with-segger-j-link-and-nxp-s32-design-studio/
但是FreeRTOS任務(wù)列表(使用Menu FreeRTOS>任務(wù)列表來顯示該視圖)不顯示任何運(yùn)行時(shí)信息:
FreeRTOS任務(wù)列表,沒有運(yùn)行時(shí)信息
這是我們將在接下來的步驟中添加的內(nèi)容。
3、跟蹤和運(yùn)行時(shí)統(tǒng)計(jì)信息
在FreeRTOSConfig.h中,確保將以下定義設(shè)置為1(打開):
啟用運(yùn)行時(shí)統(tǒng)計(jì)信息和跟蹤功能
該configUSE_TRACE_FACILITY需要使用RTOS有在任務(wù)描述當(dāng)前存儲(chǔ)的運(yùn)行時(shí)間計(jì)數(shù)器的附加數(shù)據(jù)元素,在configGENERATE_RUN_TIME_STATS自動(dòng)關(guān)上,以創(chuàng)紀(jì)錄的任務(wù)執(zhí)行時(shí)間的功能。
4、配置定時(shí)器
接下來,我們必須設(shè)置一個(gè)計(jì)時(shí)器來測量任務(wù)執(zhí)行時(shí)間。該計(jì)時(shí)器的運(yùn)行速度至少比RTOS Tick計(jì)時(shí)器快10倍。
在我們的示例中,滴答率為1 kHz:
這意味著我們的運(yùn)行時(shí)間應(yīng)至少以10 kHz運(yùn)行。
要配置這樣的計(jì)時(shí)器,我可以使用MCUXpresso配置外設(shè)工具:
外圍設(shè)備工具
在外設(shè)工具中,我們選擇了FTM0定時(shí)器(我們也可以使用任何其他定時(shí)器)。
添加FTM0
定時(shí)器配置為10 kHz:
定時(shí)器輸出頻率
我們將使用定時(shí)器中斷來增加一個(gè)計(jì)數(shù)器,所以不要忘記打開中斷:
定時(shí)器溢出中斷使能
然后單擊按鈕以更新項(xiàng)目源:
更新項(xiàng)目
切換回開發(fā)人員視角。
5、定時(shí)器ISR
接下來,我們將定時(shí)器中斷代碼添加到應(yīng)用程序:
6、添加定時(shí)器驅(qū)動(dòng)
該項(xiàng)目尚未編譯,因?yàn)楸匾尿?qū)動(dòng)程序尚未成為項(xiàng)目的一部分。要添加它們,請使用“管理SDK組件”按鈕:
管理SDK組件按鈕
然后檢查ftm驅(qū)動(dòng)程序并按OK,將額外的驅(qū)動(dòng)程序源添加到項(xiàng)目中。
FTM驅(qū)動(dòng)程序
7、向FreeRTOS添加定時(shí)器:用于運(yùn)行時(shí)統(tǒng)計(jì)的FreeRTOS定時(shí)器宏
將以下行添加到FreeRTOSConfig.h:
這告訴FreeRTOS它將用于初始化定時(shí)器的功能以及獲取定時(shí)器值的功能。
向FreeRTOSConfig.h添加了運(yùn)行時(shí)計(jì)數(shù)器設(shè)置
8、FreeRTOS Callback for Timer
現(xiàn)在我們需要添加我們配置FreeRTOS使用的兩個(gè)回調(diào)。
9、正在運(yùn)行…。
構(gòu)建和調(diào)試您的應(yīng)用程序。如果您現(xiàn)在停止應(yīng)用程序并檢查任務(wù)列表,它現(xiàn)在顯示運(yùn)行時(shí)信息:
顯示運(yùn)行時(shí)信息
10、沒有Eclipse?沒問題!
上面我使用了FreeRTOS的Eclipse Task List視圖,這是NXP為他們的基于Eclipse的IDE(MCUXpresso IDE,S32DS for ARM和Kinetis Design Studio)所做的事情。但是可以直接從應(yīng)用程序顯示該信息,例如在終端LCD顯示器上。McuOnEclipse上的FreeRTOS 包含一個(gè)使用它的shell /終端接口。
控制臺(tái)上的任務(wù)運(yùn)行時(shí)信息
下面的代碼片段顯示了如何為每個(gè)任務(wù)打印信息:
?概要
FreeRTOS運(yùn)行時(shí)統(tǒng)計(jì)是一個(gè)非常有用的功能:它顯示每個(gè)任務(wù)使用了多少時(shí)間,包括其中斷時(shí)間。我需要的只是設(shè)置一些FreeRTOS配置宏并設(shè)置周期性定時(shí)器中斷。當(dāng)然,這并不是免費(fèi)提供額外的定時(shí)器中斷以及該功能所需的RAM和FLASH,但如果需要,它可以很容易地關(guān)閉以供最終版本使用。
?鏈接
? GitHub上的示例項(xiàng)目:https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_SDK_FreeRTOS
? 使用FreeRTOS進(jìn)行性能和運(yùn)行時(shí)分析
? MCUXpresso IDE網(wǎng)頁:http://www.nxp.com/mcuxpresso/ide
? MCUXpresso IDE社區(qū):http://www.nxp.com/mcuxpresso/ide/forum
? 在Eclipse中更好的FreeRTOS調(diào)試
? McuOnEclipse庫項(xiàng)目:https://github.com/ErichStyger/McuOnEclipseLibrary/tree/master/lib/FreeRTOS/Source
? ARM Cortex-M循環(huán)計(jì)數(shù)器:https://mcuoneclipse.com/2017/01/30/cycle-counting-on-arm-cortex-m-with-dwt/
? 更好的FreeRTOS調(diào)試:https://mcuoneclipse.com/2017/03/18/better-freertos-debugging-in-eclipse/
? FreeRTOS RuntimeStats:https://www.freertos.org/rtos-run-time-stats.html
歡迎關(guān)注:
總結(jié)
以上是生活随笔為你收集整理的在Amazon FreeRTOS V10中使用运行时统计信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海康sip服务器地址_完整SIP/SDP
- 下一篇: php点加等于0,php 做数学运算时结