FreeRTOS空闲任务
生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS空闲任务
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
空閑任務在啟動調度器的時候被創建
/* 啟動調度器 */ void vTaskStartScheduler( void ) {BaseType_t xReturn;#if (configSUPPORT_STATIC_ALLOCATION == 1){......}#else{/* 創建空閑任務 */xReturn = xTaskCreate(prvIdleTask, configIDLE_TASK_NAME, configMINIMAL_STACK_SIZE, (void *)NULL, portPRIVILEGE_BIT, &xIdleTaskHandle);}#endif....if(xReturn == pdPASS){....../* 啟動調度器 */if(xPortStartScheduler() != pdFALSE){}else{}}else{......}...... }?
?
空閑任務的作用包括:保證系統至少有一個任務在運行、檢查等待終結列表中是否有任務并釋放它們。
/* 空閑任務 */ static portTASK_FUNCTION(prvIdleTask, pvParameters) {(void)pvParameters;portTASK_CALLS_SECURE_FUNCTIONS();for(;;){/* 檢查等待終結任務列表,釋放所有等待終結的任務 */prvCheckTasksWaitingTermination();#if (configUSE_PREEMPTION == 0){taskYIELD();}#endif#if ((configUSE_PREEMPTION == 1) && (configIDLE_SHOULD_YIELD == 1)){/* 空閑任務優先級所在就緒列表中,還有其他任務 */if(listCURRENT_LIST_LENGTH(&(pxReadyTasksLists[tskIDLE_PRIORITY])) > (UBaseType_t)1){/* 能運行到空閑任務,說明高優先級的任務都不在就緒態 *//* 如果有和空閑任務優先級一樣的任務,不切換的話,就要等系統節拍器去切換 *//* 在這里直接申請切換,效率更高 */taskYIELD();}else{mtCOVERAGE_TEST_MARKER();}}#endif#if (configUSE_IDLE_HOOK == 1){extern void vApplicationIdleHook(void);vApplicationIdleHook();}#endif#if (configUSE_TICKLESS_IDLE != 0){TickType_t xExpectedIdleTime;xExpectedIdleTime = prvGetExpectedIdleTime();if(xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP){vTaskSuspendAll();{configASSERT(xNextTaskUnblockTime >= xTickCount);xExpectedIdleTime = prvGetExpectedIdleTime();configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING(xExpectedIdleTime);if(xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP){traceLOW_POWER_IDLE_BEGIN();portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime);traceLOW_POWER_IDLE_END();}else{mtCOVERAGE_TEST_MARKER();}}(void)xTaskResumeAll();}else{mtCOVERAGE_TEST_MARKER();}}#endif} }?
?
其中prvCheckTasksWaitingTermination()函數,負責檢查等待終結列表并釋放所有等待終結的任務
/* 檢查等待終結任務列表,釋放所有等待終結的任務 */ static void prvCheckTasksWaitingTermination(void) {#if (INCLUDE_vTaskDelete == 1){TCB_t *pxTCB;/* 將所有等待終結的線程都釋放掉 */while(uxDeletedTasksWaitingCleanUp > (UBaseType_t)0U){/* 進入臨界區 */taskENTER_CRITICAL();{/* 從等待終結列表中獲取任務 */pxTCB = listGET_OWNER_OF_HEAD_ENTRY((&xTasksWaitingTermination));/* 將任務從等待終結列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 當前任務數減一 */--uxCurrentNumberOfTasks;/* 等待終結的任務數減一 */--uxDeletedTasksWaitingCleanUp;}/* 退出臨界區 */taskEXIT_CRITICAL();/* 釋放任務TCB */prvDeleteTCB(pxTCB);}}#endif }?
?
任務被刪除的時候,如果一個任務刪除另外一個任務,被刪除任務的堆棧和TCB立即釋放。如果一個任務刪除自己,則會將任務掛接到檢查等待終結列表,有空閑任務負責釋放。
/* 刪除任務 */ void vTaskDelete(TaskHandle_t xTaskToDelete) {TCB_t *pxTCB;/* 進入臨界區 */taskENTER_CRITICAL();{/* 通過任務句柄獲取任務TCB */pxTCB = prvGetTCBFromHandle(xTaskToDelete);/* 將任務從狀態列表中移除,狀態列表中沒有掛接任何任務 */if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){/* 將該優先級從當前任務優先級記錄中清除 */taskRESET_READY_PRIORITY(pxTCB->uxPriority);}else{mtCOVERAGE_TEST_MARKER();}/* 任務被掛接到事件列表 */if(listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem)) != NULL){/* 將任務從事件列表中移除 */(void)uxListRemove(&(pxTCB->xEventListItem));}else{mtCOVERAGE_TEST_MARKER();}/* 任務id號加一 */uxTaskNumber++;/* 該任務為當前任務 */if(pxTCB == pxCurrentTCB){/* 任務掛接到等待終結列表 */vListInsertEnd(&xTasksWaitingTermination, &(pxTCB->xStateListItem));/* 等待終結任務數加一 */++uxDeletedTasksWaitingCleanUp;portPRE_TASK_DELETE_HOOK(pxTCB, &xYieldPending);}else{/* 當前任務數減一 */--uxCurrentNumberOfTasks;/* 刪除任務TCB */prvDeleteTCB(pxTCB);/* 更新下一個要解除阻塞的時間,防止該任務是先需要解除的任務 */prvResetNextTaskUnblockTime();}traceTASK_DELETE(pxTCB);}/* 退出臨界區 */taskEXIT_CRITICAL();/* 調度器正在運行 */if(xSchedulerRunning != pdFALSE){/* 該任務為當前任務 */if(pxTCB == pxCurrentTCB){configASSERT(uxSchedulerSuspended == 0);/* 請求切換任務 */portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}} }?
總結
以上是生活随笔為你收集整理的FreeRTOS空闲任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 难以理解的软件工程师:几千行代码能搞定为
- 下一篇: 面试了8家公司,他们问了我这些机器学习题