計算RTOS的CPU的使用率及任務棧的使用情況,有助於RTOS的調試開發。可以分析多任務的設計的合理性,如果CPU的利用率為1%,說明CPU 99%的時間運行在空閑任務上,則極大的浪費CPU的性能。計算FreeRTOS的CPU使用率就要用到兩個函數vTaskList和vTaskGetRunTimeStats。通過這兩個函數獲取任務的執行狀態。
執行的結果用串口打印出來,這種調試僅用於測試而非正常項目。
1.定義一個Timer 50us進入中斷一次,最大支持計數時間:2^32 * 50us / 3600s = 59.6分鍾。運行時間超過了59.6分鍾將不准確。FreeRTOS的系統內核沒有對總的計數時間做溢出保護。
1 /** 2 * @brief Period elapsed callback in non blocking mode 3 * @note This function is called when TIM1 interrupt took place, inside 4 * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment 5 * a global variable "uwTick" used as application time base. 6 * @param htim : TIM handle 7 * @retval None 8 */ 9 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 10 { 11 /* USER CODE BEGIN Callback 0 */ 12 13 /* USER CODE END Callback 0 */ 14 if (htim->Instance == TIM1) { 15 HAL_IncTick(); 16 } 17 /* USER CODE BEGIN Callback 1 */ 18 if(htim->Instance == TIM2) 19 { 20 CPU_RunTime++; 21 } 22 /* USER CODE END Callback 1 */ 23 }
2.使能相關的宏定義FreeRTOSConfig.h
extern volatile uint32_t CPU_RunTime;
#define configUSE_TRACE_FACILITY 1 //設置為1,使用可視化追蹤功能。設置為0,就不使用。如果使用可視化追蹤,必須提供追蹤緩沖區。
#define configGENERATE_RUN_TIME_STATS 1 //為1,則該函數將總運行時間寫入*pulTotalRunTime中。pulTotalRunTime可以設置為NULL,表示忽略總運行時間
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 //用戶配置宏定義configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS都為1的時候,將使能函數vTaskList() 和 vTaskGetRunTimeStats(),如/果兩者中任何一個為0,那么這兩個函數都將被禁能
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (CPU_RunTime = 0UL)
#define portGET_RUN_TIME_COUNTER_VALUE() CPU_RunTime
3. 單獨創建一個任務統計CPU利用率
1 /* Cpu_task function */ 2 void Cpu_task(void const * argument) 3 { 4 /* USER CODE BEGIN Cpu_task */ 5 uint8_t CPU_RunInfo[512]; 6 /* Infinite loop */ 7 for(;;) 8 { 9 memset(CPU_RunInfo,0,512); 10 vTaskList((char *)&CPU_RunInfo); //獲取任務運行時間信息 11 printf("---------------------------------------------\r\n"); 12 printf("任務名 任務狀態 優先級 剩余棧 任務序號\r\n"); 13 printf("%s", CPU_RunInfo); 14 printf("---------------------------------------------\r\n"); 15 memset(CPU_RunInfo,0,512); 16 vTaskGetRunTimeStats((char *)&CPU_RunInfo); 17 printf("任務名 運行計數 使用率\r\n"); 18 printf("%s", CPU_RunInfo); 19 printf("---------------------------------------------\r\n\n"); 20 osDelay(200); /* 延時500個tick */ 21 22 } 23 /* USER CODE END Cpu_task */ 24 }
第二種方法查看CPU利用率的方利用TrueStudio IDE查看
設置方法參考:STM32CubeIDE user guide - User manual
1) #define configUSE_TRACE_FACILITY 1
2)應用程序軟件必須調用vQueueAddToRegistry()函數,使FreeRTOS隊列和FreeRTOS信號量視圖能夠顯示對象
3)freeRTOSConfig.h
#define configGENERATE_RUN_TIME_STATS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (RunTime=0UL)
#define portGET_RUN_TIME_COUNTER_VALUE() RunTime
4)tasks.c 中 ulTutoralRunTime
#if ( configGENERATE_RUN_TIME_STATS == 1 )
PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
#endif
修改為
#if ( configGENERATE_RUN_TIME_STATS == 1 )
PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
PRIVILEGED_DATA volatile static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
#endif