第二節:FreeRTOS 任務的建立、刪除、掛起、恢復
https://www.freertos.org/
https://download.csdn.net/download/zennaiheqiao/10665003
1.任務建立
1.1函式描述
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, unsigned short usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask );
建立新的任務並加入任務就緒列表。
建立一個新任務並將其新增到準備執行的任務列表中。 在FreeRTOSConfig.h中,configSUPPORT_DYNAMIC_ALLOCATION必須設定為1,或者未定義(在這種情況下預設為1),此RTOS API函式可用。
每個任務都需要用於儲存任務狀態的RAM,並由任務用作其堆疊。如果使用xTaskCreate()建立任務,則會從FreeRTOS堆自動分配所需的RAM 。如果使用xTaskCreateStatic()建立任務,則RAM由應用程式編寫者提供,因此可以在編譯時靜態分配。有關 詳細資訊,請參閱
如果您使用的是FreeRTOS-MPU,則建議使用xTaskCreateRestricted() 代替xTaskCreate()。
如果使用FreeRTOS-MPU(在官方下載包中,為Cortex-M3核心寫了兩個移植方案,一個是普通的FreeRTOS移植層,還有一個是FreeRTOS-MPU移植層。後者包含完整的記憶體保護),那麼推薦使用函式xTaskCreateRestricted()來代替xTaskCreate()。在使用FreeRTOS-MPU的情況下,使用xTaskCreate()函式可以建立執行在特權模式或使用者模式(見下面對函式引數uxPriority的描述)的任務。當執行在特權模式下,任務可以訪問整個記憶體對映;當處於使用者模式下,任務僅能訪問自己的堆疊。無論在何種模式下,MPU都不會自動捕獲堆疊溢位,因此標準的FreeRTOS堆疊溢位檢測機制仍然會被用到。xTaskCreateRestricted()函式具有更大的靈活性。
1.2引數描述
- pvTaskCode:指標,指向任務函式的入口。任務永遠不會返回(位於死迴圈內)。該引數型別TaskFunction_t定義在檔案projdefs.h中,定義為:typedefvoid (*TaskFunction_t)( void * )。
- pcName:任務描述。主要用於除錯。字串的最大長度由巨集configMAX_TASK_NAME_LEN指定,該巨集位於FreeRTOSConfig.h檔案中。
- usStackDepth:指定任務堆疊大小,能夠支援的堆疊變數數量,而不是位元組數。比如,在16位寬度的堆疊下,usStackDepth定義為100,則實際使用200位元組堆疊儲存空間。堆疊的寬度乘以深度必須不超過size_t型別所能表示的最大值。比如,size_t為16位,則可以表示的最大值是65535。
- pvParameters:指標,當任務建立時,作為一個引數傳遞給任務。
- uxPriority:任務的優先順序。具有MPU支援的系統,可以通過置位優先順序引數的portPRIVILEGE_BIT位,隨意的在特權(系統)模式下建立任務。比如,建立一個優先順序為2的特權任務,引數uxPriority可以設定為( 2 | portPRIVILEGE_BIT )。
- pvCreatedTask:用於回傳一個控制代碼(ID),建立任務後可以使用這個控制代碼引用任務。
1.3返回值
如果任務成功建立並加入就緒列表函式返回pdPASS,否則函式返回錯誤碼,具體參見projdefs.h。
1.4用法舉例
/ *要建立的任務。* /
void vTaskCode(void * pvParameters)
{
/ *引數值預期為1,因為1傳遞了
pvParameters在下面的xTaskCreate()呼叫中的值。
configASSERT(((uint32_t)pvParameters)== 1);
for(;;)
{
/ *任務程式碼在這裡。* /
}
}
/ *建立任務的函式。* /
void vOtherFunction(void)
{
BaseType_t xReturned;
TaskHandle_t xHandle = NULL;
/ *建立任務,儲存控制代碼。* /
xReturned = xTaskCreate(
vTaskCode, / *實現任務的函式。* /
“NAME”, / *任務的文字名稱。* /
STACK_SIZE, / *以字為單位的堆疊大小,而不是位元組。* /
(void *)1, / *傳遞給任務的引數。* /
tskIDLE_PRIORITY,/ *建立任務的優先順序。* /
&xHandle); / *用於傳遞建立的任務的控制代碼。* /
if(xReturned == pdPASS)
{
/ *任務已建立。使用任務的控制代碼刪除任務。* /
vTaskDelete(xHandle);
}
}
2.任務刪除
2.1 任務描述
voidvTaskDelete( TaskHandle_t xTask );
從RTOS核心管理器中刪除一個任務。任務刪除後將會從就緒、阻塞、暫停和事件列表中移除。在檔案FreeRTOSConfig.h中,必須定義巨集INCLUDE_vTaskDelete 為1,本函式才有效。
注:被刪除的任務,其在任務建立時由核心分配的儲存空間,會由空閒任務釋放。如果有應用程式呼叫xTaskDelete(),必須保證空閒任務獲取一定的微控制器處理時間。任務程式碼自己分配的記憶體是不會自動釋放的,因此刪除任務前,應該將這些記憶體釋放。
2.2引數描述
- xTask:被刪除任務的控制代碼。為NULL表示刪除當前任務。
-
void vOtherFunction(void) { TaskHandle_t xHandle = NULL; //建立任務,儲存控制代碼。 xTaskCreate(vTaskCode,“NAME”,STACK_SIZE,NULL,tskIDLE_PRIORITY,&xHandle); //使用控制代碼刪除任務。 if(xHandle!= NULL) { vTaskDelete(xHandle); } }
3.任務掛起
3.1 任務描述
void vTaskSuspend(TaskHandle_t xTaskToSuspend);
必須將INCLUDE_vTaskSuspend定義為1才能使此功能可用。有關更多資訊,請參閱RTOS配置文件。
暫停任何任務。暫停任務時,永遠不會獲得任何微控制器處理時間,無論其優先順序如何。
對vTaskSuspend的呼叫不是累積的 - 即在同一任務上呼叫vTaskSuspend()兩次仍然只需要呼叫vTaskResume()來準備掛起的任務。
3.2引數描述
xTaskToSuspend | 處理暫停的任務。傳遞NULL控制代碼將導致呼叫任務被掛起。 |
用法示例:
void vAFunction(void)
{
TaskHandle_t xHandle;
//建立一個任務,儲存控制代碼。
xTaskCreate(vTaskCode,“NAME”,STACK_SIZE,NULL,tskIDLE_PRIORITY,&xHandle);
// ...
//使用控制代碼暫停建立的任務。
vTaskSuspend(xHandle);
// ...
//在此期間,建立的任務不會執行,除非
//另一個任務呼叫vTaskResume(xHandle)。
// ...
//暫停自己
vTaskSuspend(NULL);
//除非另一個任務呼叫vTaskResume,否則我們無法到達此處
//以我們的控制代碼作為引數。
}
4.任務恢復
4.1 任務描述
void vTaskResume(TaskHandle_t xTaskToResume);
必須將INCLUDE_vTaskSuspend定義為1才能使此功能可用。有關更多資訊,請參閱RTOS配置文件。
恢復暫停的任務。
通過對vTaskSuspend()的一次或多次呼叫暫停的任務將通過單次呼叫vTaskResume()再次執行。
4.2引數描述
xTaskToResume | 處理正在準備的任務。 |
用法示例:
void vAFunction(void)
{
TaskHandle_t xHandle;
//建立一個任務,儲存控制代碼。
xTaskCreate(vTaskCode,“NAME”,STACK_SIZE,NULL,tskIDLE_PRIORITY,&xHandle);
// ...
//使用控制代碼暫停建立的任務。
vTaskSuspend(xHandle);
// ...
//在此期間,建立的任務不會執行,除非
//另一個任務呼叫vTaskResume(xHandle)。
// ...
//自己恢復暫停的任務。
vTaskResume(xHandle);
//建立的任務將再次獲得微控制器處理
//時間根據其在系統內的優先順序。
}