微信公眾號 | strongerHuang
前幾天,有小伙伴問了大概這么一個問題:RTOS有很多任務,如果沒有執(zhí)行任務了,都在延時等待(如vTaskDelay),或等待事件觸發(fā)(如xQueueReceive),CPU在干嘛?
從裸機轉向RTOS的小伙伴,不知道你有沒有過這樣的疑問?
裸機 vs 系統(tǒng)
裸機情況下,就是一個while死循環(huán):
int main(void)
{
/* 初始化 */
while(1)
{
/* 循環(huán)處理多項事情 */
}
}
換上RTOS就是為了提高CPU利用率,使其執(zhí)行多個任務(多個while):
void?Task1(void)
{
/* 初始化 */
while(1)
{
/* 處理事情1 */
}
}
void Task2(void)
{
/* 初始化 */
while(1)
{
/* 處理事情2 */
}
}
void?Task3(void)
void Task4(void)
......
通過對比裸機和操作系統(tǒng)的區(qū)別,再結合開篇的問題,你能聯(lián)想到什么?
裸機情況下,CPU永遠都在while(1)大循環(huán)中。那么,在操作系統(tǒng)下,CPU除了執(zhí)行任務中的while,其他時間都執(zhí)行到哪兒去了?
答案是:CPU在執(zhí)行操作系統(tǒng)自帶的空閑任務/線程/進程。
OS空閑任務
我們打開Windows系統(tǒng)的任務管理器,不操作電腦時,你會發(fā)現(xiàn)一個進程CPU占有率很高:
沒錯,這個進行就是系統(tǒng)空閑進程。
在RTOS實時操作系統(tǒng)中,也有一個類似這樣的線程(任務),叫空閑任務。
uCOS中空閑任務叫:OS_TaskIdleFreeRTOS中空閑任務叫:prvIdleTask
當然你在線調試帶有RTOS操作系統(tǒng)的項目時,暫停運行代碼,有很大概率CPU會執(zhí)行到空閑任務。
比如uCOS空閑函數:
void OS_TaskIdle (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtr++;
OS_EXIT_CRITICAL();
OSTaskIdleHook(); /* Call user definable HOOK */
}
}
其實,你會發(fā)現(xiàn)這個系統(tǒng)空閑函數也沒什么代碼,就是在哪兒“死循環(huán)”。
這里有一個?OSTaskIdleHook();函數是提供給用戶的,默認情況下,這個函數也是啥東西沒有,需要用戶根據自己情況添加代碼。這里可以參看我之前分享的文章:RTOS中鉤子函數HOOK的用途及用法。
所以,回到本文的問題:RTOS沒有執(zhí)行任務,CPU在干嘛?
答案是:默認情況下,啥都沒干!當然,如果你看到CPU太閑了,你也可以讓它干點事。比如在上面的 OSTaskIdleHook() 函數里面添加一句打印輸出:
printf("CPU在偷懶了...nr");
最后,你對RTOS實時操作系統(tǒng)內核了解多少?有多少小伙伴閱讀過內核源碼?