任務協程(Co-routines)
任務和協程使用不同的API,因此他們不能使用同一個隊列或信號量傳遞數據。
協程僅用在資源非常少的微處理器中,現在一般很少使用。
任務
概述
調度器主要的職責是,在任務切入切出時保存上下文環境(寄存器值、堆棧內容)。為了實現這點,每個任務都需要有自己的堆棧。當任務切出時,它的執行環境會被保存在該任務的堆棧中,這樣當再次運行時,就能從堆棧中正確的恢復上次的運行環境。-
特性
- 簡單
- 沒有使用限制
- 支持完全搶占
- 支持優先級
- 每個任務都有自己的堆棧,消耗RAM較多
- 如果使用搶占,必須小心的考慮可重入問題
-
狀態
- 運行 正在執行,此時占用CPU
- 就緒 具備執行的能力等待被調度
- 阻塞 等待某個時序或外部中斷中斷
-
掛起 掛起狀態的任務同樣對調度器無效,必須調用api后才能進入就緒隊列
關系圖
-
優先級
每個任務都需要被指定一個0->configMAX_PRIORITIES數值的優先級(在Cortex-M3中數值越大,優先級越低)如果某架構硬件支持CLZ(或類似)指令(計算前導零的數目,Cortex-M3是支持該指令的,從ARMv6T2才支持這個指令),并且打算在移植層使用這個特性來優化任務調度機制,需要有一些步驟,首先將FreeRTOSConfig.h中configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1,并且最大優先級數目configMAX_PRIORITIES不能大于32。除此之外,configMAX_PRIORITIES可以設置為任意值,但是考慮到configMAX_PRIORITIES設置越大,RAM消耗也越大,一般設置為滿足使用的最小值
任何數量的任務可以共享同一個優先級。如果宏configUSE_TIME_SLICING未定義或著宏configUSE_TIME_SLICING定義為1,處于就緒態的多個相同優先級任務將會以時間片切換的方式共享處理器。
任務函數如下
void vATaskFunction( voidvoid *pvParameters )
{
for( ;; )
{
/*-- 應用程序代碼放在這里. --*/
}
/* 任務不可以從這個函數返回或退出。在較新的FreeRTOS移植包中,如果
試圖從一個任務中返回,將會調用configASSERT()(如果定義的話)。
如果一個任務確實要退出函數,那么這個任務應調用vTaskDelete(NULL)
函數,以便處理一些清理工作。*/
vTaskDelete( NULL );
}
任務函數決不應該返回,因此通常任務函數都是一個死循環。
- IDLE TASK 和 IDLE TASK HOOK
- RTOS為了確保系統至少有一個任務在運行會自動創建一個具有最低優先級的空閑任務(idle task),除此之外空閑任務沒有其他任何作用,因此合理的剝奪空閑任務的處理器時間是可取的。
- 空閑任務鉤子是一個函數,每一個空閑任務周期被調用一次。如果你想將任務程序功能運行在空閑優先級上,可以有兩種選擇:
在一個空閑任務鉤子中實現這個功能:因為FreeRTOS必須至少有一個任務處于就緒或運行狀態,因此鉤子函數不可以調用可能引起空閑任務阻塞的API函數(比如vTaskDelay()或者帶有超時事件的隊列或信號量函數)。
-
創建一個具有空閑優先級的任務去實現這個功能:這是個更靈活的解決方案,但是會帶來更多RAM開銷。
創建一個空閑鉤子步驟如下:
- 在FreeRTOSConfig.h頭文件中設置configUSE_IDLE_HOOK為1;
-
定義一個函數,名字和參數原型如下所示:
void vApplicationIdleHook( void );
```
通常,**使用這個空閑鉤子函數設置CPU進入低功耗模式**。
2016.2.27