FreeRTOS多任務(LED + BEEP)


函數流程

int main(void)
{
    /* 第一步:開發板硬件初始化 */
    BSP_Init();

    /* 第二步:創建APP應用任務,所有的應用任務都可以放在這個函數里面 */
    AppTaskCreate();
    
    /* 第三步:啟動FreeRTOS,開始多任務調度,啟動成功則不返回 */
    vTaskStartScheduler();
    
    while (1)
    {
        
    }
}

創建APP應用任務,

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

pvTaskCode 任務只是永不退出的 C 函數,實現通常是一個死循環。參數pvTaskCode 只是一個指向任務的實現函數的指針(效果上僅僅是函數名)。


pcName 具有描述性的任務名。這個參數不會被 FreeRTOS 使用。其只是單純地用於輔助調試。識別一個具有可讀性的名字總是比通過句柄來識別容易得多。

應用程序可以通過定義常量 config_MAX_TASK_NAME_LEN 來定義任務名的最大長度——包括’\0’結束符。如果傳入的字符串長度超過了這個最大值,字符串將會自動被截斷。

usStackDepth 當任務創建時,內核會分為每個任務分配屬於任務自己的唯一狀態。

usStackDepth 值用於告訴內核為它分配多大的棧空間。這個值指定的是棧空間可以保存多少個字(word),

而不是多少個字節(byte)。比如說,如果是 32 位寬的棧空間,傳入的 usStackDepth值為 100,
則將會分配 400 字節的棧空間(100 * 4bytes)。棧深度乘以棧寬度的結果千萬不能超過一個 size_t 類型變量所能表達的最大值。


應用程序通過定義常量 configMINIMAL_STACK_SIZE 來決定空閑任務任用的棧空間大小。
在 FreeRTOS 為微控制器架構提供的Demo 應用程序中,賦予此常量的值是對所有任務的最小建議值。

如果你的任務會使用大量棧空間,那么你應當賦予一個更大的值。
沒有任何簡單的方法可以決定一個任務到底需要多大的棧空間。

計算出來雖然是可能的,但大多數用戶會先簡單地賦予一個自認為合理的值,
然后利用 FreeRTOS 提供的特性來確證分配的空間既不欠缺也不浪費。

pvParameters 任務函數接受一個指向 void 的指針(void*)。pvParameters 的值即是傳遞到任務中的值。

uxPriority 指定任務執行的優先級。優先級的取值范圍可以從最低優先級 0 到最高優先級(configMAX_PRIORITIES – 1)。
configMAX_PRIORITIES 是一個由用戶定義的常量。優先級號並沒有上限(除了受限於采用的數據類型和系統的有效內存空間),
但最好使用實際需要的最小數值以避免內存浪費。如果 uxPriority 的值超過了(configMAX_PRIORITIES – 1),
將會導致實際賦給任務的優先級被自動封頂到最大合法值。


 

 

void vTaskLed1(void *pvParameters)
{
    /* 任務都是一個無限,不能返回 */
    while(1)
    {
        LED1_ON;
        /* 阻塞延時,單位ms */        
        vTaskDelay( 500 );
        LED1_OFF;
        vTaskDelay( 500 );
    }

}

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

  

調度器保證總是在所有可運行的任務中選擇具有最高優先級的任務,並使其進入運行態。
如果被選中的優先級上具有不止一個任務,調度器會讓這些任務輪流執行。這種行為方式在本例中可以明顯看出來。
兩個測試任務被創建在同一個優先級上,並且一直是可運行的。所以每個任務都執行一個”時間片”,
任務在時間片起始時刻進入運行態,在時間片結束時刻又退出運行態。
圖  中 t1 與 t2 之間的時段就等於一個時間片。

 

 

 

 




免責聲明!

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



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