FreeRtos——任務刪除,改變任務優先級


以下轉載自安富萊電子: http://forum.armfly.com/forum.php

vTaskDelete() API 函數
任務可以使用 API 函數 vTaskDelete()刪除自己或其它任務。
任務被刪除后就不復存在,也不會再進入運行態。
空閑任務的責任是要將分配給已刪除任務的內存釋放掉。因此有一點很重要,那就
使用 vTaskDelete() API 函數的任務千萬不能把空閑任務的執行時間餓死
需要說明一點,只有內核為任務分配的內存空間才會在任務被刪除后自動回收。任
務自己占用的內存或資源需要由應用程序自己顯式地釋放。

在使用這個API函數之前,需要配置INCLUDE_vTaskDelete == 1。

剛開始,看歷程有點不解,給一個任務句柄初始化為NULL,為什么刪除任務(非自身任務)的時候,傳入的還是句柄,句柄不是初始化為NULL了嗎?思前想后覺得應該是xTaskCreate創建函數會更改任務句柄的值,果然,xTaskCreate函數接受的任務句柄是個二級指針,就算我們給任務句柄初始化為NULL,xTaskCreate函數執行之后,任務句柄會被更改為一個非NULL指針。所以就有了下面的代碼:

//初始化任務句柄

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

//創建任務

static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任務函數名 */
                "Task Led1",         /* 任務名,字符串形式,方便調試 */
                 512,                /* 棧大小,單位為字,即4個字節 */
                 (void *)&task_led3, /* 任務形參 */
                 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)即可。

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

 

 

 函數 vTaskPrioritySet 用於實現 FreeRTOS 任務優先級的修改。
第 1 個參數是任務句柄,用於區分不同的任務。
第 2 個參數是給任務配置的新優先級。
使用這個函數要注意以下問題:
1. 使用此函數需要在 FreeRTOSConfig.h 配置文件中配置如下宏定義為 1
#define INCLUDE_vTaskPrioritySet 1
2. 如果第一個參數里面填的是 NULL,即數值 0 的話,那么配置的就是當前正在執行的任務。
3. 如果被修改的任務的優先級,修改后高於正在執行的任務,將執行任務切換,切換到修改好的高優先級任務。
4. 第二個參數數值不可大於等於 FreeRTOSConfig.h 文件中的宏定義:
#define configMAX_PRIORITIES 配置的數值。

 

使用這個函數要注意以下問題:
1. 使用此函數需要在 FreeRTOSConfig.h 配置文件中配置如下宏定義為 1
#define INCLUDE_vTaskPriorityGet 1
2. 如果第一個參數里面填的是 NULL,即數值 0 的話,那么獲取的優先級就是當前正在執行的任務。

改變任務優先級
調度器總是在所有就緒態任務中選擇具有最高優先級的任務,並使其進入運行態。
本例即是通過調用 vTaskPrioritySet() API 函數來改變兩個任務的相對優先級,以達到
對調度器這一行為的演示。
在不同的優先級上創建兩個任務。這兩個任務都沒有調用任何會令其進入阻塞態的
API 函數,所以這兩個任務要么處於就緒態,要么處於運行態——這種情形下,調度器
選擇具有最高優先級的任務來執行。
所以,我們創建任務一LED亮,優先級1,任務二,蜂鳴器響,優先級2。這樣在不阻塞的情況下,只會執行任務2,蜂鳴器響,但是,我們在任務二中,修改任務一的優先級,使它高於任務二。步驟如下:

 

void vTaskLed1(void *pvParameters)
{
    /* 任務都是一個無限,不能返回 */
    int *piParameters;
    piParameters=(int *)pvParameters;
    while(1)
    {
        if(*piParameters==1)
        {
            LED1( ON );
            /* 阻塞延時,單位ms */        
            vTaskDelay( 500 );
            LED1( OFF );    
            vTaskDelay( 500 );
        }
        else if(*piParameters==2)
        {
            LED2( ON );
            /* 阻塞延時,單位ms */        
            vTaskDelay( 500 );
            LED2( OFF );    
            vTaskDelay( 500 );
        }
        else if(*piParameters==3)
        {
            LED3( ON );

        }
    }    
}
/*********************************************************************************
  * @ 函數名  : vTaskBeep
  * @ 功能說明: Beep 任務
  * @ 參數    : pvParameters,當任務創建的時候傳進來,可以沒有  
  * @ 返回值  : 無
  ********************************************************************************/
void vTaskBeep(void *pvParameters)
{
    /* 任務都是一個無限循環,不能返回 */
    while(1)
    {
        BEEP_ON;    

    }    
}

 

上面代碼,任務2,beep優先級為2,任務1,led優先級為1,沒有阻塞操作,調度器只執行優先級高的任務2,但是,我們更改任務2代碼如下:

void vTaskBeep(void *pvParameters)
{
    /* 任務都是一個無限循環,不能返回 */
    while(1)
    {
        BEEP_ON;
        vTaskPrioritySet(xHandleTaskLED1,3);
        
    }    
}

把任務一優先級設成3,這樣任務2運行到vTaskPrioritySet ()函數后(就算vTaskPrioritySet 函數后面還有程序都不會再執行),調度器會重新選擇優先級更高的執行。

再試試我們用vTaskPrioritySet 的NULL參數修改自身優先級為1,這樣任務1,2優先級都是1,這樣都可以運行。

void vTaskBeep(void *pvParameters)
{
    /* 任務都是一個無限循環,不能返回 */
    while(1)
    {
        BEEP_ON;
        vTaskPrioritySet(NULL,1);
    }    
}

 


免責聲明!

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



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