由於FreeRTOS沒有像其他實時操作系統一樣提供CPU使用率統計的功能,無法直觀地評估CPU的使用情況,所以在此提供一種計算CPU使用率的方法。
一、原理
此種方法計算CPU使用率的原理爲:
1、在系統啓動後,所有用戶任務都未開始運行時,統計一段時間T(如1s)內空閒任務被調用的次數M,此時可認爲這個次數是CPU佔用率最小(接近0)時能夠調用空閒任務的最大次數。
2、任務開始運行後,在滴答時鐘中斷處理函數中,每隔T時間,記錄空閒任務被調用的次數m。
3、CPU佔用率爲:(1-m/M)*100%
二、實現
爲了減少此功能對CPU資源的佔用,所以不使用空閒鉤子函數,而是直接在文件中加入相關代碼,並儘量精簡。
1.task.c
在文件開頭定義變量:
//--------------------------------------------
#if(usercfgCPU_USAGE_CALCULATE==1)
static unsigned long max_idle_cnt=0;
static unsigned short idle_cntl=0;
static unsigned long idle_cnth=0;
static unsigned short tick_cnt=0;
unsigned short OSCPUusage=0;
#endif
//--------------------------------------------
在xTaskIncrementTick()函數最後面加上CPU使用率計算語句,爲了減小開銷,沒有做限幅等數據有效性判斷:
//--------------------------------------------
#if(usercfgCPU_USAGE_CALCULATE==1)
tick_cnt++;
if(tick_cnt>=usercfgCPU_USAGE_CALC_PERIOD)
{
OSCPUusage=10000-idle_cnth*10000/max_idle_cnt;//0-10000->0.00-100.00%
idle_cntl=0;
idle_cnth=0;
tick_cnt=0;
}
#endif
//--------------------------------------------
在portTASK_FUNCTION()函數(即Idletask)最後面加上空閒任務統計語句:
//--------------------------------------------
#if(usercfgCPU_USAGE_CALCULATE==1)
idle_cntl++;
if(idle_cntl>=100)//idle_cntl是爲了防止idle_cnth溢出而設置的分頻計數器
{
idle_cntl=0;
idle_cnth++;
}
#endif
//--------------------------------------------
在文件最後面加上空閒任務最大調用次數統計函數:
//--------------------------------------------
void uTaskCPUUsageInit(void)
{
vTaskDelay(2);//synchronizewithclocktick
taskENTER_CRITICAL();
max_idle_cnt=0;
idle_cntl=0;
idle_cnth=0;
tick_cnt=0;
taskEXIT_CRITICAL();
//爲了防止idle_cnth==usercfgCPU_USAGE_CALC_PERIOD時被清零,所以只統計前80%的時間
vTaskDelay(usercfgCPU_USAGE_CALC_PERIOD*4/5);//calcmax_idle_cnt
taskENTER_CRITICAL();
max_idle_cnt=idle_cnth*5/4;
taskEXIT_CRITICAL();
}
#endif
//--------------------------------------------
2.task.h
在文件最後聲明變量和函數:
//--------------------------------------------
#if(usercfgCPU_USAGE_CALCULATE==1)
extern unsigned short OSCPUusage;
void uTaskCPUUsageInit(void);
#endif
//--------------------------------------------
3.FreeRTOSConfig.h
在文件最後聲明是否使用CPU使用率統計功能及CPU使用率統計週期:
//--------------------------------------------
#define usercfgCPU_USAGE_CALCULATE 1
#ifdef usercfgCPU_USAGE_CALCULATE
#define usercfgCPU_USAGE_CALC_PERIOD 500//ms
#endif
//--------------------------------------------
4.main.c
在Task_Start()函數中調用uTaskCPUUsageInit(),注意必須在Task_Create()創建其他用戶任務之前調用。需要注意的是,使用uTaskCPUUsageInit()時會導致系統延時啓動。初始化完成之後,即可通過OSCPUusage觀察CPU使用率。
//--------------------------------------------
void Task_Start(void*p_arg)
{
#if(usercfgCPU_USAGE_CALCULATE==1)
uTaskCPUUsageInit();
#endif
(void)&p_arg;
Task_Create();//創建用戶任務
for(;;)
{
vTaskDelay(TASK_START_RATE);
}
}
//--------------------------------------------
原創文章,轉載請註明出處。
如有疑問或建議,請在回覆中說明,謝謝!