FreeRTOS—-改變任務優先級,任務刪除


vTaskPrioritySet() API  函數可以用於在調度器啟動后改變任何任務的優先級。

函數原型:

void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );

uxTaskPriorityGet() API 函數用於查詢一個任務的優先級。

函數原型:unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );

調度器總是在所有就緒態任務中選擇具有最高優先級的任務,並使其進入運行態。

修改任務優先級的任務實現:

 

任務在查詢和修改自己的優先級時,並沒有使用一個有效的句柄——使用 NULL代替。只有在某個任務需要引用其它任務的時候才會用到任務句柄。好比任務 1 想要改變任務 2 的優先級,為了讓任務 1 能夠使用到任務 2 的句柄,在任務 2 被創建時其句柄就被獲得並保存下來。如下面注釋所示:

執行流程圖如下:

   刪除任務

vTaskDelete() API 函數

  任務可以使用 API 函數 vTaskDelete()刪除自己或其它任務。

  任務被刪除后就不復存在,也不會再進入運行態。

  空閑任務的責任是要將分配給已刪除任務的內存釋放掉。因此有一點很重要,那就是使用 vTaskDelete() API 函數的任務千萬不能把空閑任務的執行時間餓死。

  需要說明一點,只有內核為任務分配的內存空間才會在任務被刪除后自動回收。任務自己占用的內存或資源需要由應用程序自己顯式地釋放。

函數原型:  void vTaskDelete( xTaskHandle pxTaskToDelete );

[eg]  : 任務 1 在 main()中創建在優先級 1 上。任務 1 運行時,以優先級 2 創建任務 2。現在任務 2 具有最高優先級,所以會立即得到執行。

  任務 2 什么也沒有做,只是刪除自己。可以通過傳遞 NULL 值以 vTaskDelete()來刪除自己,但是為了純粹的演示,傳遞的是任務自己的句柄。

  當任務 2 被自己刪除之后,任務 1 成為最高優先級的任務,所以繼續執行,調用vTaskDelay()阻塞一小段時間。

  當任務 1 進入阻塞狀態后,空閑任務得到執行的機會。空閑任務會釋放內核為已刪除的任務 2 分配的內存。

  任務 1 離開阻塞態后,再一次成為就緒態中具有最高優先級的任務,因此會搶占空閑任務。又再一次創建任務 2,如此往復。

 函數執行流程:

 

 
         

static TaskHandle_t xHandleTaskLED1 = NULL;
static TaskHandle_t xHandleTaskBeep = NULL;

static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任務函數名 */
                "Task Led1",         /* 任務名,字符串形式,方便調試 */
                 512,                /* 棧大小,單位為字,即4個字節 */
                 NULL,               /* 任務形參 */
                 1,                  /* 優先級,數值越大,優先級越高 */
                 &xHandleTaskLED1);  /* 任務句柄 */
    
    xTaskCreate(vTaskBeep,"Task Beep",512,NULL,2,&xHandleTaskBeep);
}

 

 //在任務beep中刪除led任務

void vTaskBeep(void *pvParameters)
{
    /* 任務都是一個無限循環,不能返回 */
    while(1)
    {
        BEEP_ON;
    /* 阻塞延時,單位ms */        
        vTaskDelay( 20 );
        BEEP_OFF;    
        vTaskDelay( 500 );
        if(xHandleTaskLED1 != NULL) vTaskDelete(xHandleTaskLED1);
    }    
}

led的任務句柄,雖然初始化為NULL,但是任務創建函數執行之后,任務句柄(是個一級指針)會被二級指針改變,所以當它不是NULL的時候,證明led任務被創建,就可以在beep中將其刪除,如果要刪除beep任務自身,vTaskDelete(NULL)即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM