目录
一、任务创建和删除的API函数
二、任务创建和删除(动态方法)
任务的创建和删除本质就是调用FreeRTOS的API函数
API函数 | 描述 |
xTaskCreate() | 动态方式创建任务 |
xTaskCreateStatic() | 静态方式创建任务 |
vTaskDelete | 删除任务(删除的是创建好的任务) |
动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均由FreeRTOS从FreeRTOS给管理的堆中分配。
静态创建任务:任务放入任务控制块以及任务的栈空间所需的内存,需要用户分配提供。
动态创建任务函数
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); /*任务句柄,就是任务的任务控制块*/
}
返回值 | 描述 |
pdPASS | 任务创建成功 |
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY | 任务创建失败 |
实现动态创建任务流程
1、将宏onfigSUPPORT_DYNAMIC_ALLOCAT配置为1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
2、定义函数入口参数
3、编写任务函数
此函数创建的任务会立刻进入就绪态,由任务调度器来执行,找到优先级最高的函数去执行。
动态创建任务内部实现
1、申请堆栈内存或者任务快内存。
2、TCB结构体成员赋值
3、添加新任务到就绪列表中
静态创建任务
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);
返回值 | 描述 |
NULL | 用户没有提供相应的内存,任务创建失败 |
其他值 | 任务句柄,任务创建成功 |
实现静态创建任务
1、将宏configSUPPORT_STATIC_ALLOCATION
#define configSUPPORT_STATIC_ALLOCATION 0
/* 1: 支持静态申请内存, 默认: 0 */
2、定义空闲任务&定时器任务的任务堆栈及TCB
3、实现两个接口函数
4、定义函数入口参数
5、编写任务函数
此函数创建的任务会立刻进入就绪态,由任务调度器调度运行
1、TCB结构体成员赋值
2、添加新任务到就绪列表中
任务删除函数
void TaskDelete(TaskHandle_t xTaskToDelete);
形参 | 描述 |
xTaskToDelete | 带删除任务的任务句柄 |
被删除的任务将从就绪任务列表、阻塞态任务列表、挂起态任务列表和事件列表中删除。
注意:
1、当传入的参数为NULL,则代表删除任务本身(当前正在运行的任务)
2、空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存,则需要由用户在任务被删除前提前释放,否则将导致内存泄漏。
删除任务流程
1、使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为1
2、入口参数输入需要删除的任务句柄(NULL代表删除本身)
内部实现过程
1、获取所需要删除任务的控制块:通过传入的任务句柄,判断所需要删除哪个任务,NULL代表删除自身。
2、将被删除任务,一处所在列表。将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表。
3、判断所需要删除的任务
(1)删除任务自身,需要添加等待删除列表,内存释放将在空闲任务执行。
(2)删除其他任务,释放内存,任务数量。
4、更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务。
任务创建和删除-动态方法
1、主要是两个函数:
(1)xTaskCreate()
(2)vTaskDelete()
2、我们总共设计四个任务,分别是:start_task、task1、task2、task3
并且设置四个任务的功能如下:
第一步:将宏 configSUPPORT_DYNAMIC_ALLOCATION配置为1,它的配置在FreeRTOSConfig.h中进行配置。我们默认为1,是动态创建的配置。
#define configSUPPORT_DYNAMIC_ALLOCATION 1
/* 1: 支持动态申请内存, 默认: 1 */
第二步:动态创建任务函数入口函数的编写
首先我们跳进去,我们把原形复制出来
xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
然后我们修改,建议用括号做一下强转,这样编译不会出现警告,不然会有很多警告的,任务函数,我们创建的是开始任务,所以要创建的任务是start_task,其中任务名字和任务函数一模一样就好,
xTaskCreate((TaskFunction_t )start_task, /* 任务函数 */
(const char* )"start_task", /* 任务名称 */
(uint16_t )START_STK_SIZE, /* 任务堆栈大小 */
(void* )NULL, /* 传入给任务函数的参数 */
(UBaseType_t )START_TASK_PRIO, /* 任务优先级 */
(TaskHandle_t* )&StartTask_Handler); /* 任务句柄 */
第三步:我们创建三个任务
任务一:
void task1(void *pvParameters)
{
while(1)
{
printf("Task1正在运行!!!\r\n");
LED0_TOGGLE(); /* LED0闪烁 */
LED1_TOGGLE();
vTaskDelay(500); /* 延时500ticks */
}
}
任务二:
void task2(void *pvParameters)
{
float test = 0.0;
while(1)
{ printf("Task2正在运行!!!\r\n");
// printf("小羽嵌入式编程\r\n");
test += 0.01f; /* 更新数值 */
printf("test_num: %0.4f\r\n", test); /* 打印数值 */
vTaskDelay(1000); /* 延时1000ticks */
}
}
任务三:
void task3(void *pvParameters)
{
uint8_t key=0;
while(1)
{
key =key_scan(0);
if(key==KEY0_PRES)
{
if(Task1Task_Handler!=NULL)
{
printf("删除task1任务\r\n");
vTaskDelete(Task1Task_Handler);
Task1Task_Handler = NULL;
}
}
vTaskDelay(10);
}
}
我已验证,完全正确,有疑问请私聊