FreeRTOS最基本的功能是任务管理,任务管理有创建与删除任务
此函数用来创建一个任务,使用此函数来创建任务所需的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
删除一个函数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);
}
}
大体流程就是:在主函数创建开始任务函数,在开始任务函数中开始任务任务函数,删除开始任务函数,再编写各个任务函数