任務可以以下列狀態之一存在:
- 運行
當任務實際執行時,它被稱為處於運行狀態。它目前正在使用處理器。如果運行RTOS的處理器只有一個內核,那么在任何給定時間只能有一個處於運行狀態的任務。
- 准備
就緒任務是那些能夠執行的任務(它們不處於“阻塞”或“掛起”狀態),但當前未執行,因為具有相同或更高優先級的不同任務已處於“正在運行”狀態。
- 阻止
如果任務目前正在等待時間或外部事件,則說該任務處於阻塞狀態。例如,如果任務調用vTaskDelay(),它將阻塞(置於阻塞狀態)直到延遲時間到期 - 一個時間事件。任務也可以阻塞以等待隊列,信號量,事件組,通知或信號量事件。處於阻塞狀態的任務通常有一個“超時”時間段,在此之后,任務將超時,並且即使未發生任務等待的事件也會被解除阻塞。
處於阻塞狀態的任務不使用任何處理時間,並且不能選擇進入運行狀態。
- 暫停
與處於阻塞狀態的任務類似,處於暫停狀態的任務不能被選擇為進入運行狀態,但處於暫停狀態的任務不會超時。相反,只有通過分別通過vTaskSuspend()和xTaskResume()API調用顯式指令才能進入或退出暫停狀態。
有效的任務狀態轉換
任務優先級
每個任務都分配了一個從0到(configMAX_PRIORITIES - 1)的優先級,其中configMAX_PRIORITIES在FreeRTOSConfig.h中定義。
如果正在使用的端口實現了使用“計數前導零”類型指令(用於在單條指令中進行任務選擇)的端口優化任務選擇機制,並且FreeRTOSConfig.h中的configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1,則configMAX_PRIORITIES不能高於32。在所有其他情況下,configMAX_PRIORITIES可以在合理范圍內使用任何值 - 但由於RAM使用效率的原因應保持在實際所需的最小值。
低優先級數字表示低優先級任務。該空閑任務的優先級為零(tskIDLE_PRIORITY)。
FreeRTOS調度程序確保處於“就緒”或“正在運行” 狀態的任務始終獲得處理器(CPU)時間,優先於處於就緒狀態的較低優先級任務。換句話說,放置到運行狀態的任務始終是能夠運行的最高優先級任務。
任何數量的任務都可以共享相同的優先級。如果未定義configUSE_TIME_SLICING,或者將configUSE_TIME_SLICING設置為1,則等待優先級的就緒狀態任務將使用時間片循環調度方案共享可用處理時間。
實施一項任務
任務應該具有以下結構:
void vATaskFunction(void * pvParameters) { for(;;) { - 這里的任務應用代碼。 - } / *任務不得試圖從其實施中返回 功能或其他退出。在較新的FreeRTOS端口 試圖這樣做將導致configASSERT()是 如果它被定義,則稱為。如果有必要完成任務 退出然后讓任務調用vTaskDelete(NULL)來確保 它的出口很干凈。* / vTaskDelete(NULL); }TaskFunction_t類型被定義為一個返回void的函數,並將void指針作為其唯一參數。所有實現任務的功能都應該是這種類型的。該參數可用於將任何類型的信息傳遞到任務中 - 這由幾個 標准演示應用程序任務演示。
任務函數不應該返回,因此通常以連續循環的形式實現。同樣,請參閱RTOS演示應用程序以獲取大量示例。
任務通過調用xTaskCreate()或xTaskCreateStatic()來創建,並通過調用vTaskDelete()來刪除。
任務創建宏
任務功能可以任選地使用portTASK_FUNCTION和portTASK_FUNCTION_PROTO宏定義。提供這些宏以允許將編譯器特定的語法分別添加到函數定義和原型。除非在正在使用的端口的文檔(目前僅限於PIC18 fedC端口)中特別聲明,否則不需要使用它們。
上面顯示的功能原型可以寫成:
void vATaskFunction(void * pvParameters);要么,
portTASK_FUNCTION_PROTO(vATaskFunction,pvParameters);同樣,上面的函數也可以寫成:
portTASK_FUNCTION(vATaskFunction,pvParameters) { for(;;) { - 這里的任務應用代碼。 - } }
空閑任務
當RTOS調度程序啟動時,空閑任務會自動創建,以確保總是有至少一個能夠運行的任務。如果在就緒狀態下有更高優先級的應用程序任務,它將以盡可能最低的優先級創建,以確保它不使用任何CPU時間。
空閑任務負責將由RTOS分配的內存釋放到已被刪除的任務。因此,在使用vTaskDelete()函數來確保空閑任務不會處理時間不足的應用程序中非常重要。空閑任務沒有其他主動功能,所以在所有其他條件下可以合理地使微控制器時間減少。
應用程序任務可以共享空閑任務優先級(tskIDLE_PRIORITY)。有關如何配置此行為的信息,請參閱configIDLE_SHOULD_YIELD 配置參數。
空閑任務鈎子
空閑任務掛鈎是在空閑任務的每個周期中被調用的函數。如果您希望應用程序功能以空閑優先級運行,則有兩種選擇:- 在空閑任務掛鈎中實現功能。
必須至少有一個任務已准備好運行。因此,hook函數不會調用可能導致空閑任務阻塞的任何API函數(例如,vTaskDelay()或具有阻塞時間的隊列或信號量函數)。協同例程在鈎子函數中被阻塞是可以的。
- 創建一個空閑優先級任務來實現該功能。
這是一個更靈活的解決方案,但具有更高的RAM使用開銷。
要創建一個閑置鈎子:
- 在FreeRTOSConfig.h中將configUSE_IDLE_HOOK設置為1 。
- 定義一個具有以下名稱和原型的函數:
void vApplicationIdleHook(void);