在Amazon FreeRTOS V10中使用運行時統計信息

来源:https://www.cnblogs.com/foxclever/archive/2018/08/11/9459691.html
-Advertisement-
Play Games

在MCU on Eclipse網站上看到Erich Styger在8月2日發的博文,一篇關於在Amazon FreeRTOS V10中使用運行時統計信息的文章,本人覺得很有啟發,特將其翻譯過來以備參考。原文網址:https://mcuoneclipse.com/2018/08/02/tutorial ...


  在MCU on Eclipse網站上看到Erich Styger在8月2日發的博文,一篇關於在Amazon FreeRTOS V10中使用運行時統計信息的文章,本人覺得很有啟發,特將其翻譯過來以備參考。原文網址:https://mcuoneclipse.com/2018/08/02/tutorial-using-runtime-statistics-with-amazon-freertos-v10/

 

  FreeRTOS包含一個很好的功能,可以向我提供有關每個任務在系統上運行的時間的信息:

 

FreeRTOS運行時信息

  本教程解釋了FreeRTOS運行時統計功能以及如何打開和使用它。

軟體和工具

  在本文中,我使用以下內容:

  • MCUXpresso IDE 10.2.1
  • FRDM-K64F板
  • 來自MCUXpresso SDK 2.4.0的Amazon FreeRTOS V10.0.1

  但是當然可以使用任何其他工具/ IDE或FreeRTOS版本(FreeRTOS至少應該是9.0.0或更高版本)。

  使用以下步驟,還可以使用FreeRTOS任務運行時信息收集來更新現有項目。

怎麼運行的

  FreeRTOS使用用戶/應用程式特定的計時器來測量任務執行時間。為此,RTOS中的每個任務描述符都有一個累積計數器,用於添加為該任務花費的計時器滴答。當任務獲得CPU時間時,當前計時器滴答計數被記憶,當RTOS切換出該任務時,則記憶當前計時器滴答計數。然後將對應於任務執行時間的增量時間添加到任務執行時間計數器。

  我需要配置FreeRTOS,並將以下巨集設置為1以執行運行時分析:

1 #define configGENERATE_RUN_TIME_STATS 1

另外,需要提供以下兩個巨集:

1 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
2 portGET_RUN_TIME_COUNTER_VALUE()

  RTOS使用它來配置運行時計數器計時器並獲取計時器值。

  運行時計數器在每個任務描述符中存儲為32位值,這意味著對於每個任務,我對系統的RAM要求將增加4個位元組:

 

FreeRTOS TCB中的ulRunTimeCounter

   假設計數器周期為10 kHz(0.1 ms),這意味著變數將在大約5天後溢出。

  此外,RTOS在task.c中維護額外的全局變數:

1 #if ( configGENERATE_RUN_TIME_STATS == 1 )
2 
3     PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
4 
5     PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL;       /*< Holds the total amount of execution time as defined by the run time counter clock. */
6 
7 #endif

  第一個變數用於記住任務切換的時間,第二個變數是系統的總運行時間。這是在任務切換時發生的事情(內核函數vTaskSwitchContext):

 1 /* 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. */
 2 
 3 if( ulTotalRunTime > ulTaskSwitchedInTime )
 4 
 5 {
 6 
 7     pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
 8 
 9 }
10 
11 else
12 
13 {
14 
15     mtCOVERAGE_TEST_MARKER();
16 
17 }
18 
19 ulTaskSwitchedInTime = ulTotalRunTime;

  通常,周期性定時器中斷用於計算執行時間,並且定時器頻率應該是嘀嗒中斷頻率的大約10倍(比如說“Hello”到“奈奎斯特 - 香農”採樣定理)。這意味著如果我的滴答中斷是1 kHz,我的運行時分析定時器頻率應該是10 kHz。

  運行時統計信息通常帶有兩個數字:

  • 絕對(時間)數字
  • 百分比

  下麵是一個文本任務列表,其中包含右側的運行時信息:

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%)

  絕對數字是運行時間計時器滴答數(TCB中的ulRunTimeCounter)以及此計數器相對於總運行時間的百分比(task.c中的ulTotalRunTime)。

  對於IDLE任務,它顯示了這一點:

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是定時器計數器(在本例中使用0.1 ms定時器,因此它意味著IDLE任務運行約3秒(0x7C35 / 10 => 3179 ms)並使用91%的運行時間。

  問題可能是:中斷花費的時間是多少?答案是RTOS不知道中斷,它只知道任務使用了多少運行時間計時器。或者換句話說:FreeRTOS運行時計數器顯示的運行時* includes*中斷的時間。

教程:使用FreeRTOS進行運行時分析

  在下一節中,我將展示如何使用FreeRTOS啟用運行時分析。基本步驟是:

  • 創建一個新項目(如果尚未存在)
  • 更新FreeRTOSConfig.h
  • 初始化和配置計時器
  • 添加鉤子/回調到應用程式

1、創建項目

  創建一個基於你的目標板的項目:

 

項目創建的目標板

  確保包含FreeRTOS:

 

項目的FreeRTOS選項

2、添加FreeRTOS任務

  接下來添加一個任務,例如:

 1 #include "FreeRTOS.h"
 2 
 3 #include "task.h"
 4 
 5  
 6 
 7 static void MyTask(void *pvParameters) {
 8 
 9   for(;;) {
10 
11     vTaskDelay(pdMS_TO_TICKS(100));
12 
13   }
14 
15 }

  在main()內部,創建一個任務並啟動調度程式:

 1 /* create task */
 2 
 3  if (xTaskCreate(MyTask, "MyTask", 500/sizeof(StackType_t), NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {
 4 
 5    for(;;){} /* error */
 6 
 7  }
 8 
 9  vTaskStartScheduler(); /* start RTOS */
10 
11  for(;;) {
12 
13      /* should not get here */
14 
15  }

 

添加FreeRTOS任務

構建和調試該項目,只是為了確保一切正常。

 

調試FreeRTOS任務

  要在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任務列表(使用Menu FreeRTOS>任務列表來顯示該視圖)不顯示任何運行時信息:

 

FreeRTOS任務列表,沒有運行時信息

  這是我們將在接下來的步驟中添加的內容。

3、跟蹤和運行時統計信息

  在FreeRTOSConfig.h中,確保將以下定義設置為1(打開):

1 #define configGENERATE_RUN_TIME_STATS 1 /* 1: generate runtime statistics; 0: no runtime statistics */
2 
3 #define configUSE_TRACE_FACILITY      1 /* 1: include additional structure members and functions to assist with execution visualization and tracing, 0: no runtime stats/trace */

 

啟用運行時統計信息和跟蹤功能

  該configUSE_TRACE_FACILITY需要使用RTOS有在任務描述當前存儲的運行時間計數器的附加數據元素,在configGENERATE_RUN_TIME_STATS自動關上,以創紀錄的任務執行時間的功能。

4、配置定時器

  接下來,我們必須設置一個計時器來測量任務執行時間。該計時器的運行速度至少比RTOS Tick計時器快10倍。

  在我們的示例中,滴答率為1 kHz:

1 #define configTICK_RATE_HZ ((TickType_t)1000)

  這意味著我們的運行時間應至少以10 kHz運行。

  要配置這樣的計時器,我可以使用MCUXpresso配置外設工具:

 

外圍設備工具

  在外設工具中,我們選擇了FTM0定時器(我們也可以使用任何其他定時器)。

 

添加FTM0

  定時器配置為10 kHz:

 

定時器輸出頻率

  我們將使用定時器中斷來增加一個計數器,所以不要忘記打開中斷:

 

定時器溢出中斷使能

  然後單擊按鈕以更新項目源:

 

更新項目

  切換回開發人員視角。

5、定時器ISR

  接下來,我們將定時器中斷代碼添加到應用程式:

 1 #include "fsl_ftm.h"
 2 
 3 static uint32_t RTOS_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */
 4 
 5  
 6 
 7 void FTM0_IRQHandler(void) {
 8 
 9   /* Clear interrupt flag.*/
10 
11   FTM_ClearStatusFlags(FTM0, kFTM_TimeOverflowFlag);
12 
13   RTOS_RunTimeCounter++; /* increment runtime counter */
14 
15 }

6、添加定時器驅動

  該項目尚未編譯,因為必要的驅動程式尚未成為項目的一部分。要添加它們,請使用“管理SDK組件”按鈕:

 

管理SDK組件按鈕

  然後檢查ftm驅動程式並按OK,將額外的驅動程式源添加到項目中。

 

FTM驅動程式

7、向FreeRTOS添加定時器:用於運行時統計的FreeRTOS定時器巨集

  將以下行添加到FreeRTOSConfig.h:

1 extern void RTOS_AppConfigureTimerForRuntimeStats(void);
2 
3 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()   RTOS_AppConfigureTimerForRuntimeStats()
4 
5 extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(void);
6 
7 #define portGET_RUN_TIME_COUNTER_VALUE()           RTOS_AppGetRuntimeCounterValueFromISR()

  這告訴FreeRTOS它將用於初始化定時器的功能以及獲取定時器值的功能。

 

向FreeRTOSConfig.h添加了運行時計數器設置

8FreeRTOS Callback for Timer

  現在我們需要添加我們配置FreeRTOS使用的兩個回調。

 1 void RTOS_AppConfigureTimerForRuntimeStats(void) {
 2 
 3   RTOS_RunTimeCounter = 0;
 4 
 5   EnableIRQ(FTM0_IRQn);
 6 
 7 }
 8 
 9  
10 
11 uint32_t RTOS_AppGetRuntimeCounterValueFromISR(void) {
12 
13   return RTOS_RunTimeCounter;
14 
15 }

9、正在運行...

  構建和調試您的應用程式。如果您現在停止應用程式並檢查任務列表,它現在顯示運行時信息:

 

顯示運行時信息

10、沒有Eclipse?沒問題!

  上面我使用了FreeRTOS的Eclipse Task List視圖,這是NXP為他們的基於Eclipse的IDE(MCUXpresso IDE,S32DS for ARM和Kinetis Design Studio)所做的事情。但是可以直接從應用程式顯示該信息,例如在終端LCD顯示器上。McuOnEclipse上的FreeRTOS 包含一個使用它的shell /終端介面。

 

控制臺上的任務運行時信息

  下麵的代碼片段顯示瞭如何為每個任務列印信息:

 1 #if configGENERATE_RUN_TIME_STATS
 2 
 3   ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); /* get total time passed in system */
 4 
 5   ulTotalTime /= 100UL; /* For percentage calculations. */
 6 
 7 #endif
 8 
 9 ...
10 
11 #if configGENERATE_RUN_TIME_STATS && configUSE_TRACE_FACILITY
12 
13       /* runtime */
14 
15       UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x");
16 
17       UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), taskStatus.ulRunTimeCounter);
18 
19       if (ulTotalTime>0) { /* to avoid division by zero */
20 
21         /* What percentage of the total run time has the task used?
22 
23            This will always be rounded down to the nearest integer.
24 
25            ulTotalRunTime has already been divided by 100. */
26 
27         ulStatsAsPercentage = taskStatus.ulRunTimeCounter/ulTotalTime;
28 
29         if (ulStatsAsPercentage>0) {
30 
31           UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" (");
32 
33           UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), ulStatsAsPercentage, ' ', 3);
34 
35           UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)"%)");
36 
37         } else {
38 
39           /* If the percentage is zero here then the task has consumed less than 1% of the total run time. */
40 
41           UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" ( <1%)");
42 
43         }
44 
45       }
46 
47       buf[0] = '\0';
48 
49       UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_RUNTIME);
50 
51       CLS1_SendStr(buf, io->stdOut);
52 
53 #endif
54 
55       CLS1_SendStr((unsigned char*)"\r\n", io->stdOut);

概要

  FreeRTOS運行時統計是一個非常有用的功能:它顯示每個任務使用了多少時間,包括其中斷時間。我需要的只是設置一些FreeRTOS配置巨集並設置周期性定時器中斷。當然,這並不是免費提供額外的定時器中斷以及該功能所需的RAM和FLASH,但如果需要,它可以很容易地關閉以供最終版本使用。

鏈接

  • GitHub上的示例項目:https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_SDK_FreeRTOS
  • 使用FreeRTOS進行性能和運行時分析
  • MCUXpresso IDE網頁:http://www.nxp.com/mcuxpresso/ide
  • MCUXpresso IDE社區:http://www.nxp.com/mcuxpresso/ide/forum
  • 在Eclipse中更好的FreeRTOS調試
  • McuOnEclipse庫項目:https://github.com/ErichStyger/McuOnEclipseLibrary/tree/master/lib/FreeRTOS/Source
  • ARM Cortex-M迴圈計數器:https://mcuoneclipse.com/2017/01/30/cycle-counting-on-arm-cortex-m-with-dwt/
  • 更好的FreeRTOS調試:https://mcuoneclipse.com/2017/03/18/better-freertos-debugging-in-eclipse/
  • FreeRTOS RuntimeStats:https://www.freertos.org/rtos-run-time-stats.html

 歡迎關註:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學到新東西就記錄一下。也許正好有人需要~~~~~~ 由於需要記錄當前線上用戶,emmmm又是沒做過的。。。 本來想用資料庫的形式,但是想想這麼簡單的功能百度肯定有。遨游一波百度,有所收穫。。。。 雖然老是那麼幾篇文章重覆。。。。 大概就是在用戶登錄時Session記錄下數據,前臺獲取展示。下麵這個文 ...
  • 以前在學習STM32時候關註過STM32的位帶操作,那時候只是知道位帶是啥,用來幹嘛用,說句心裡話,並沒有深入去學習,知其然而不知其所以然。但一直在心中存在疑惑,故今日便仔細看了一下,寫下心得供日後參考。 位帶操作,我所理解的是就是像51單片機那樣驅動IO引腳一樣,比如要驅動P1埠的第一個引腳直接 ...
  • whoami // 查看當前用戶名稱 ipconfig // 查看本機ip信息,可加 /all 參數 netstat -ano // 查看埠清況 dir c:\ // 查看目錄 type c:\Users\admin\Desktop\1.txt // 查看制定位置文件內容,一般為文本文件 echo ...
  • 打開虛擬機,用Xshell連接之前,首先我們要獲取IP的地址 先輸入獲取 IP的命令 ip addr 獲取ipifup (網卡名字) #網卡啟動ifdown (網卡名字) #網卡關閉 沒有獲取到的話 我們要開始按照下麵的順序排查故障: 沒有獲取到的話 我們要開始按照下麵的順序排查故障: 按照上面的步 ...
  • LVM學習邏輯捲管理創建邏輯捲遇到的問題 1 實驗環境 系統 | 內核 | 發行版本 | | CentOS | 2.6.32 754.2.1.el6.x86_64 | CentOS release 6.10 (Final) 由於是最小化安裝沒有xfs命令, 安裝如下包支持此命令 2 用gdisk分區 ...
  • 系統狀態查看命令: w 查看用戶 top 系統進程監控 uptime 查看某台伺服器運行了多久 htop 更加先進的互動式監控工具(需要安裝) iotop 監控並實時顯示磁碟IO輸入和輸出和程式進程(需要安裝) iftop 網路帶寬監控(需要安裝) 查看進程: ps ps -ef 查看所有進程 ps ...
  • 嵌入式里有時候也會和音頻打交道,比如最近特別火的智能音箱產品,離不開前端的音頻信號採集、降噪,中間的語音識別(ASR)、自然語言處理(NLP),以及後端的文語合成(TTS)、音頻播放。音頻信號採集是處理聲音的第一步,要採集音頻就離不開PCM編碼,音頻採集完成自然需要保存,waveform格式(.wa... ...
  • 在shell腳本中,變數分兩種,系統變數和自定義變數。 系統預設變數是系統自帶的一些變數,如path為路徑變數 用戶自定義變數為在編寫吧腳本的時候自己定義的一些變數 變數名命名規則 首個字元必須為字母“a-z和A-Z” 中間不能有空格,但是可以使用下劃線“_” 不能使用標點符號 不能使用bash中的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...