任务的创建和删除
一、动态任务的创建和删除:
1、在FreeRTOSconfig.h中配置configSUPPORT_DYNAMIC_ALLOCATION为1。
2、创建开始任务:先定义相对应的任务名称,任务优先级,任务堆栈大小,任务句柄,然后创建任务。
具体例子:
/*start_task设置任务优先级,任务堆栈大小,任务句柄*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task(void* pvParameters);
/*task1设置任务优先级,任务堆栈大小,任务句柄*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1(void* pvParameters);
/*task2设置任务优先级,任务堆栈大小,任务句柄*/
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2(void* pvParameters);
/*task3设置任务优先级,任务堆栈大小,任务句柄*/
#define TASK3_PRIO 4
#define TASK3_STACK_SIZE 128 //单位是字
TaskHandle_t task3_handler;
void task3(void* pvParameters);
void freertos_demo()
{
xTaskCreate( (TaskFunction_t ) start_task, //指向任务函数的指针
(const char * ) "start_task", //任务名字
(const uint16_t ) START_TASK_STACK_SIZE, //任务堆栈大小
(void * ) NULL,
(UBaseType_t ) START_TASK_PRIO,
(TaskHandle_t * ) &start_task_handler );
vTaskStartScheduler(); //开启任务调度,意味着要看那个优先级和就绪态了
}
/*开始任务,用来创建任务1,2,3,只执行一次*/
void start_task(void* pvParameters)
{
taskENTER_CRITICAL(); //进入临界区保护
xTaskCreate( (TaskFunction_t ) task1, //指向任务函数的指针
(const char * ) "task1", //任务名字
(const uint16_t ) TASK1_STACK_SIZE, //任务堆栈大小
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(TaskHandle_t * ) &task1_handler );
xTaskCreate( (TaskFunction_t ) task2, //指向任务函数的指针
(const char * ) "task2", //任务名字
(const uint16_t ) TASK2_STACK_SIZE, //任务堆栈大小
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(TaskHandle_t * ) &task2_handler );
/*
xTaskCreate( (TaskFunction_t ) task3, //指向任务函数的指针
(const char * ) "task3", //任务名字
(const uint16_t ) TASK3_STACK_SIZE, //任务堆栈大小
(void * ) NULL,
(UBaseType_t ) TASK3_PRIO,
(TaskHandle_t * ) &task3_handler );
*/
vTaskDelete(NULL);
taskEXIT_CRITICAL(); //退出临界区保护
}
/*任务1,LED0 500ms翻转一次*/
void task1(void* pvParameters)
{
while(1)
{
printf("任务1正在运行!!! \r\n");
LED0=!LED0;
vTaskDelay(500); //taskdelay的延时基准是1ms
}
}
/*任务2,LED1 500ms翻转一次*/
void task2(void* pvParameters)
{
while(1)
{
printf("任务2正在运行!!! \r\n");
LED1=!LED1;
vTaskDelay(500); //taskdelay的延时基准是1ms
}
}
/*任务3,判断KEY0,按下KEY0删除task1*/
void task3(void* pvParameters)
{
uint8_t key;
key = 0; //无符号整数变量定义完之后一定要记得赋值,不然key的值未知会出错。
while(1)
{
printf("任务3正在运行!!! \r\n");
key = KEY_Scan(0);
if(key == KEY0_PRES)
{
if(task1_handler != 0)
{
printf("删除任务1\r\n");
vTaskDelete(task1_handler);
task1_handler = NULL;
} //这里判断的作用是防止重复释放本来已经被释放的内存
}
vTaskDelay(10);
}
}
需要注意的点:
1、在开始任务中要进入临界区保护,进入临界区保护的目的是为了保证任务1、2、3的完整初始化创建,函数为 taskENTER_CRITICAL()和 taskEXIT_CRITICAL()
。
2、开启任务调度的函数 vTaskStartScheduler()
。
3、删除任务的函数vTaskDelete(TaskHandle_t)
,参数为任务句柄,填NULL默认是当前任务。
二、创建静态任务
1、需将宏configSUPPORT——STATIC_ALLOCATION
配置为1。
2、定义空闲任务&定时器任务的任务堆栈和TCB(任务控制块)。
3、实现两个接口函数vApplicationGetIdleTaskMemory()
和vApplicationGetTimerTaskMemory()
。
4、定义函数入口参数。
5、编写任务函数。
操作过程:
1、需将宏configSUPPORT——STATIC_ALLOCATION
配置为1。
2、定义空闲任务任务堆栈和TCB和接口函数vApplicationGetidleTaskMemory()
。
将上面宏定义改了之后编译发现
然后我们直接全局搜索找到该函数的定义位置
重写完是这样的:
3、实现软件定时器的PCB和相应vApplicationGetTimerTaskMemory()
的接口函数:
这样我们就重写完成了基于动态任务改写的静态任务啦,关键就在于定义宏configSUPPORT_STATIC_ALLOCATION置为1,然后在重写空闲任务的vApplicationGetIdleTaskMemory()和配置空闲任务的堆栈大小和tcb控制块,其实软件定时器的改写是可选内容。