FreeRTOS學習筆記(1)---任務建立與刪除API函式(動態函式)
FreeRTOS最基本的功能是任務管理,任務管理有建立與刪除任務
1.函式xTaskCreate()
此函式用來建立一個任務,使用此函式來建立任務所需的RAM(隨機儲存器)會從FreeRTOS的堆中分配,因此必須提供記憶體管理檔案,預設使用heap_4.c這個記憶體管理檔案,而巨集configSUPPORT_DYNAMIC_ALLOCATION必須為1(FreeRTOSconfig.h)
新建立的任務預設是就緒態的,如果當前沒有比它更高優先順序的任務進行,那麼次任務就立即進入執行太開始執行
函式原型:(task.c)
pyTaskCode:任務函式
pcName:任務名字,一般用於跟蹤和除錯,任務名字不超過configMAX_TASK_NAME_LEN.(16)
usStackDepth:任務堆疊大小,注意實際申請到的堆疊是usStackDepth的四倍。其中空閒任務的任務堆疊大小為configMINIMAL_STACK_SIZE
pvParameters:傳遞給任務的函式
usPriotiry:任務優先順序。範圍0~configMAX_PRIORITIES-1(32)
pxCreatedTask:任務控制代碼,任務建立成功後會返回此任務的控制代碼,這個控制代碼其實是任務的任務堆疊,慈溪桉樹就是用來儲存這個任務控制代碼,其他API函式可能會使用到這個控制代碼
樣例:
在主函式裡新增建立任務函式
在主函式前面新增巨集定義和結構體引用
//任務優先順序 #define START_TASK_PRIO 1 //任務堆疊大小 #define START_STK_SIZE 128 //任務控制代碼 TaskHandle_t StartTask_Handler; //任務函式 void start_task(void *pvParameters);
主函式裡面新增
xTaskCreate( (TaskFunction_t) start_task,
(const char * ) "wanghziqun",
(uint16_t) START_STK_SIZE,
(void * ) NULL,
(UBaseType_t) START_TASK_PRIO,
(TaskHandle_t *) &StartTask_Handler );
建立完任務後別忘了開啟任務排程
vTaskStartScheduler();
注意:填寫控制代碼的時候,別忘了前面的“&”符號;一般pvParameters中寫NULL
2.函式vTaskDelete()
刪除一個函式xTaskCreate()或者是xTaskCreateStatic()建立的任務,被刪除了任務不再存在,也不能再使用此控制代碼
動態建立任務的函式,刪除後此任務之前申請的堆疊和控制寬記憶體會在空閒任務中被釋放
函式原型:(task.c)
注意:(1)括號裡面填寫刪除控制代碼,刪除自己則寫NULL
(2)如果某任務進行,同時此任務被刪除,則會保持正在執行狀態(比如led正在亮,這個任務被刪除,那麼led會一直亮),但記憶體中此任務的堆疊已經被收回
練習:建立3個任務:
start_task:用來建立其他兩個任務
task1_task:當此任務執行5次後呼叫vTaskDelete(),刪除任務task2_task,此任務也會控制LED0的閃爍
task2_task:控制LED1閃爍
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "FreeRTOS.h"
#include "task.h"
//任務優先順序
#define START_TASK_PRIO 1
//任務堆疊大小
#define START_STK_SIZE 128
//任務控制代碼
TaskHandle_t StartTask_Handler;
//任務函式
void start_task(void *pvParameters);
//任務優先順序
#define TASK1_TASK_PRIO 2
//任務堆疊大小
#define TASK1_STK_SIZE 128
//任務控制代碼
TaskHandle_t Task1Task_Handler;
//任務函式
void task1_task(void *pvParameters);
//任務優先順序
#define TASK2_TASK_PRIO 3
//任務堆疊大小
#define TASK2_STK_SIZE 128
//任務控制代碼
TaskHandle_t Task2Task_Handler;
//任務函式
void task2_task(void *pvParameters);
int main(void)
{
delay_init(); //延時函式初始化
LED_Init(); //初始化LED
//建立開始任務
xTaskCreate( (TaskFunction_t) start_task,
(const char * ) "wanghziqun",
(uint16_t) START_STK_SIZE,
(void * ) NULL,
(UBaseType_t) START_TASK_PRIO,
(TaskHandle_t *) &StartTask_Handler );
vTaskStartScheduler();
}
//開始任務任務函式
void start_task(void *pvParameters)
{
xTaskCreate( (TaskFunction_t) task1_task,
(const char * ) "task1_task",
(uint16_t) TASK1_STK_SIZE,
(void *) NULL,
(UBaseType_t) TASK1_TASK_PRIO,
(TaskHandle_t *) &Task1Task_Handler);
xTaskCreate( (TaskFunction_t) task2_task,
(const char *) "task2_task",
(uint16_t) TASK2_STK_SIZE,
(void *) NULL,
(UBaseType_t) TASK2_TASK_PRIO,
(TaskHandle_t *) &Task2Task_Handler);
vTaskDelete(StartTask_Handler); //NULL
}
//task1任務函式
void task1_task(void *pvParameters)
{
char a = 0;
while(1)
{
LED0=~LED0;
a++;
vTaskDelay(1500);
if(a == 5)
{
vTaskDelete(NULL);
}
}
}
//task2任務函式
void task2_task(void *pvParameters)
{
while(1)
{
LED1=~LED1;
vTaskDelay(1500);
}
}
大體流程就是:在主函式建立開始任務函式,在開始任務函式中開始任務任務函式,刪除開始任務函式,再編寫各個任務函式