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