FreeRTOS-01-任務相關函數

3 任務相關API函數

任務相關函數以下:shell

任務建立和刪除API函數api

任務建立和刪除實驗(動態方法)數組

任務建立和刪除實驗(靜態方法)函數

任務掛起和恢復API函數測試

任務掛起和恢復實驗ui

3.1 任務建立API函數(動態方法)

函數原型:code

#include "FreeRTOS.h"
#include "task.h"

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
    const char * const pcName,
    const configSTACK_DEPTH_TYPE usStackDepth,
    void * const pvParameters,
    UBaseType_t uxPriority,
    TaskHandle_t * const pxCreatedTask );

函數描述:使用動態方法建立一個任務,任務控制塊和任務堆棧在函數內建立。最新建立的任務初始化爲就緒態,若是當前沒有更高優先級的任務運行,則馬上變爲運行態。blog

函數參數說明:內存

參數名 說明
pxTaskCode 任務函數,一般爲一個無限循環。
pcName 任務名字,名稱長度有限制,在FreeRTOSConfig.h中有定義configMAX_TASK_NAME_LEN。
usStackDepth 任務堆棧大小,實際申請到的堆棧是usStackDepth的4倍。configMINIMAL_STACK_SIZE定義的是空閒任務堆棧大小。
pvParameters 傳遞給任務函數的參數
uxPriority 任務優先級,範圍0~configMAX_PRIORITIES-1。
pxCreatedTask 任務句柄,任務建立成功之後會返回此任務的任務句柄, 這個句柄其實就是 任務的任務堆棧。 此參數就用來保存這個任務句柄。其餘 API 函數可能會使 用到這個句柄。若是任務句柄不須要使用,能夠被設置爲NULL。

返回值:字符串

pdPASS:任務建立成功。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY: 任務建立失敗,由於堆內存不足!

3.2 任務建立函數(靜態方法)

函數原型:

#include "FreeRTOS.h"
#include "task.h"

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
    const char * const pcName,
    const uint32_t ulStackDepth,
    void * const pvParameters,
    UBaseType_t uxPriority,
    StackType_t * const puxStackBuffer,
    StaticTask_t * const pxTaskBuffer );

函數描述:使用靜態方法建立一個任務。任務所須要的RAM須要用戶來提供。

函數參數說明:

參數名 說明
pxTaskCode 任務函數,一般爲一個無限循環。
pcName 任務名字,名稱長度有限制,在FreeRTOSConfig.h中有定義configMAX_TASK_NAME_LEN。
usStackDepth 任務堆棧大小,靜態建立任務的堆棧由用戶給出,一般爲一個數組,這個參數就是數組的大小。
pvParameters 傳遞給任務函數的參數
uxPriority 任務優先級,範圍0~configMAX_PRIORITIES-1。
puxStackBuffer 任務堆棧,通常爲數組,數組類型爲StackType_t類型。
pxTaskBuffer 任務控制塊

返回值:

NULL:任務建立失敗,puxStackBuffer或pxTaskBuffer爲空。
其餘值: 任務建立成功,返回任務的任務句柄。

3.3 任務刪除API函數

函數原型:

void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;

函數描述:刪除任務,刪除以後的任務再也不存在,也不能再使用此函數的句柄。若是任務使用的是xTaskCreate()建立的,此任務被刪除後此任務以前申請的堆棧和控制塊內存會在任務中被釋放掉。

函數參數:xTaskToDelete要刪除的任務的任務句柄。

返回值:

3.4 任務建立和刪除實驗(動態方法)

建立兩個任務,這兩個任務的功能以下:

task00:此任務每一個1000ms打印一次字符串,調用5次以後調用vTaskDelete()函數刪除task01。

task01:此任務爲普通任務,間隔500ms打印一次字符串,和task00一樣的任務優先級。

task00任務建立代碼:

configSTACK_DEPTH_TYPE Task00_STACK_SIZE = 5;
UBaseType_t  Task00_Priority = 1;
TaskHandle_t Task00_xHandle;

void vTask00_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task00 cnt %u...", cnt);
        if (cnt == 4)
            vTaskDelete(Task01_xHandle);
        cnt++;
        vTaskDelay(1000);
    }
}

xTaskCreate(vTask00_Code, "task00", Task00_STACK_SIZE, NULL, Task00_Priority, &Task00_xHandle);

task01任務建立代碼:

configSTACK_DEPTH_TYPE Task01_STACK_SIZE = 5;
UBaseType_t  Task01_Priority = 1;
TaskHandle_t Task01_xHandle;

void vTask01_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task01 cnt %u...", cnt);
        cnt++;
        vTaskDelay(500);
    }
}

xTaskCreate(vTask01_Code, "task01", Task01_STACK_SIZE, NULL, Task01_Priority, &Task01_xHandle);

編譯,運行,測試結果符合預期,task00運行5秒以後刪除了task01:

image-20210717164936914

3.5 任務建立和刪除實驗(靜態方法)

使用靜態方式建立一個任務,該任務每一個1秒打印一個字符串:

#define STATIC_STACK_SIZE 5
UBaseType_t  Static_Task_Priority = 1;
StaticTask_t Static_xTaskBuffer;
StackType_t  Static_xStack[STATIC_STACK_SIZE];
TaskHandle_t Static_xhandle = NULL;  //任務句柄

void static_task_code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" static task cnt %u...", cnt);
        cnt++;
        vTaskDelay(1000);
    }
}

Static_xhandle = xTaskCreateStatic (static_task_code,
        "static task",
        STATIC_STACK_SIZE,
        NULL,
        Static_Task_Priority,
        Static_xStack,
        &Static_xTaskBuffer);

3.6 vTaskDelay()

函數原型:

#include "FreeRTOS.h"
#include "task.h"

void vTaskDelay( const TickType_t xTicksToDelay );

函數描述:調用該函數的任務將進入阻塞態,中斷一段固定的時鐘週期。

函數參數:xTicksToDelay表示調用函數的任務的阻塞態保持時間。延時達到以後將進入就緒態。例如:當時鍾計數到10000時,函數調用了vTaskDelay(100),而後任務進入阻塞態,而且保持阻塞態直到時鐘計數到10100。

宏pdMS_TO_TICKS()能夠被使用來延時毫秒。例如:調用vTaskDelay( pdMS_TO_TICKS(100) ),任務將進入阻塞態100毫秒。

3.7 任務掛起函數

函數原型:

#include 「FreeRTOS.h」
#include 「task.h」
void vTaskSuspend( TaskHandle_t pxTaskToSuspend );

函數描述:將一個任務設置爲掛起態。一個任務在掛起態將不會被調度轉爲運行態。將任務從掛起態移出來的惟一方式是調用vTaskResume()函數。

函數參數:pxTaskToSuspen表示須要掛起的任務句柄。一個任務能夠經過設置參數爲NULL來掛起本身。

3.8 調度器掛起函數

函數原型:

#include 「FreeRTOS.h」
#include 「task.h」
void vTaskSuspendAll( void );

函數描述:掛起調度器,但保留中斷使能。當調度器被掛起時,若是一箇中斷須要請求上下文切換,中斷請求將保持等待直到調度器從掛起中恢復。調度器從掛起態恢復須要調用xTaskResumeAll()函數。vTaskSuspendAll()支持嵌套使用,當要恢復調度器運行時,vTaskSuspendAll()函數被調用幾回就須要調用xTaskResumeAll()函數幾回。

3.9 任務恢復函數

函數原型:

#include 「FreeRTOS.h」
#include 「task.h」
void vTaskResume( TaskHandle_t pxTaskToResume );

函數描述:將一個任務從掛起態轉換爲就緒態。任務必須是以前使用vTaskSuspend()函數進入的掛起態。

函數參數:pxTaskToResume須要恢復的任務句柄。

3.10 調度器恢復函數

函數原型:

#include 「FreeRTOS.h」
#include 「task.h」
BaseType_t xTaskResumeAll( void );

函數描述:恢復調度器爲調度狀態。調度器必須是以前使用vTaskSuspendAll()函數進入的掛起狀態。

返回值:pdTRUE:調度器轉換爲活躍狀態。

pdFALSE:調度器嵌套調用了vTaskSuspendAll(),調度器依然保持掛起狀態。

3.11 任務掛起和恢復實驗

建立兩個任務,任務二建立以後就掛起,任務三建立以後延時5秒以後,恢復任務二的運行。

代碼大體實現以下:

/* test suppend task */
configSTACK_DEPTH_TYPE Task02_STACK_SIZE = 5;
UBaseType_t  Task02_Priority = 2;
TaskHandle_t Task02_xHandle;

configSTACK_DEPTH_TYPE Task03_STACK_SIZE = 5;
UBaseType_t  Task03_Priority = 1;
TaskHandle_t Task03_xHandle;

void vTask02_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task02 cnt %u...", cnt);
        cnt++;
        vTaskDelay(1000);
    }
}

void vTask03_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task03 cnt %u...", cnt);
        cnt++;
        vTaskDelay(1000);
        if (cnt == 5)
            vTaskResume(Task02_xHandle);
    }
}

void create_task_test_suppend(void)
{
    if (xTaskCreate(vTask02_Code, "suppend task02", Task02_STACK_SIZE, 
        NULL, Task02_Priority, &Task02_xHandle) != pdPASS)
        PRINT("creat task failed!\n");
    if (xTaskCreate(vTask03_Code, "suppend task03", Task03_STACK_SIZE, 
        NULL, Task03_Priority, &Task03_xHandle) != pdPASS)
        PRINT("creat task failed!\n");
    vTaskSuspend(Task02_xHandle);
}

編譯運行,獲得的結果以下:

$ ./build/freertos-simulator 
 task03 cnt 0...
 task03 cnt 1...
 task03 cnt 2...
 task03 cnt 3...
 task03 cnt 4...
 task02 cnt 0...
 task03 cnt 5...
 task02 cnt 1...
 task03 cnt 6...
 task02 cnt 2...
 task03 cnt 7...
 task02 cnt 3...
 task03 cnt 8...

3.11 調度器掛起和恢復實驗

建立兩個任務,任務四建立以後運行,任務五建立以後延時5秒以後,掛起調度器,而後恢復調度器。

代碼大體實現以下:

configSTACK_DEPTH_TYPE Task04_STACK_SIZE = 5;
UBaseType_t  Task04_Priority = 2;
TaskHandle_t Task04_xHandle;

configSTACK_DEPTH_TYPE Task05_STACK_SIZE = 5;
UBaseType_t  Task05_Priority = 1;
TaskHandle_t Task05_xHandle;

void vTask04_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task04 cnt %u...", cnt);
        cnt++;
        vTaskDelay(1000);
    }
}

void vTask05_Code(void *para)
{
    static unsigned int cnt = 0;
    for (;;)
    {
        PRINT(" task05 cnt %u...", cnt);
        cnt++;
        vTaskDelay(1000);
        if (cnt == 5) {
            vTaskSuspendAll();
            PRINT("... ...\n");
            xTaskResumeAll();
        }
    }
}

void create_task_test_suppend(void)
{
    if (xTaskCreate(vTask04_Code, "suppend task04", Task04_STACK_SIZE, 
        NULL, Task04_Priority, &Task04_xHandle) != pdPASS)
        PRINT("creat task failed!\n");
    if (xTaskCreate(vTask05_Code, "suppend task05", Task05_STACK_SIZE, 
        NULL, Task05_Priority, &Task05_xHandle) != pdPASS)
        PRINT("creat task failed!\n");
}

編譯運行:

task04 cnt 0...
 task05 cnt 0...
 task04 cnt 1...
 task05 cnt 1...
 task04 cnt 2...
 task05 cnt 2...
 task04 cnt 3...
 task05 cnt 3...
 task04 cnt 4...
 task05 cnt 4...
 task04 cnt 5...
... ...

 task05 cnt 5...
 task04 cnt 6...
 task05 cnt 6...
 task04 cnt 7...
 task05 cnt 7...
相關文章
相關標籤/搜索