CPU占用率涉及兩個函數: 1.空閑任務函數 OS_TaskIdle 2.統計函數 OS_TaskStat
空閑任務是其他任務都沒就緒時運行的任務,幫助統計任務記錄空閑任務運行的次數OSIdleCtr。這個任務是程序必須使用的,不能用軟件刪除。
void OS_TaskIdle (void *p_arg)
{
p_arg = p_arg; //防止編譯器報錯,沒有用到P_ARG變量
for (;;) { //任務都是一個死循環
OS_ENTER_CRITICAL(); //關閉中斷
OSIdleCtr++; //每運行一次都會記錄下
OS_EXIT_CRITICAL(); //開放中斷
OSTaskIdleHook(); //每運行一次空閑任務調用的勾函數
}
}
統計函數每秒計算一次處理器單位時間內的被任務占用時間,可以通過 OS_TASK_STAT_EN 置一來打開。
#if OS_TASK_STAT_EN > 0u
void OS_TaskStat (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u;
#endif
p_arg = p_arg; //防止編譯器報錯
while (OSStatRdy == OS_FALSE) { //OS_TICKS_PER_SEC時鐘節拍
OSTimeDly(2u * OS_TICKS_PER_SEC / 10u); //直到操作系統就緒才允許運行統計任務
}
OSIdleCtrMax /= 100uL; //OSIdleCtrMax空閑任務0.1s內運行次數的最大值,這個值是在 OSStatInit函數中確定的。該函數運行時其他任務還沒有運行,cpu只運行空閑函數。這時候就可以計算出可以0.1s中最多跑多少個空閑任務。這里有疑問,每次調用統計任務這個值都被除1次。。。。。。好像不對啊。
if (OSIdleCtrMax == 0uL) {
OSCPUUsage = 0u; //如果這個最大值小于100統計錯了,清零。
#if OS_TASK_SUSPEND_EN > 0u //如果啟用掛起任務函數
(void)OSTaskSuspend(OS_PRIO_SELF); //把當前的統計任務掛起(退出統計任務)
#else
for (;;) { //如果沒有啟用
OSTimeDly(OS_TICKS_PER_SEC); //利用 OSTimeDly進行任務調度(退出統計任務)
}
#endif
}
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtrRun = OSIdleCtr; //獲取上一秒內空閑任務的運行次數
OSIdleCtr = 0uL; //同時清空空閑任務計數器為下一次統計做準備 OS_EXIT_CRITICAL();
OSCPUUsage = (INT8U)(100uL - OSIdleCtrRun / OSIdleCtrMax);
OSTaskStatHook(); //調用勾函數
#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
OS_TaskStatStkChk(); //檢查每個任務的堆棧
#endif
OSTimeDly(OS_TICKS_PER_SEC / 10u); //積累下一次0.1秒的空閑任務運行值。
}
}