FreeRTOS的任务创建和删除
1,任务创建和删除的API函数
任务的创建和删除本质就是调用FreeRTOS的API函数
动态创建任务:
任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配。
静态创建任务:
任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供。
动态创建任务函数
BaseType_t xTaskCreate
(
TaskFunction_t pxTaskCode, /* 指向任务函数的指针 */
const char * const pcName, /* 任务名字,最大长度 configMAX_TASK_NAME_LEN */
const configSTACK_DEPTH_TYPE usStackDepth, /* 任务堆栈大小,注意字为单位 */
void * const pvParameters, /* 传递给任务函数的参数 */
UBaseType_t uxPriority, /* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */
TaskHandle_t * const pxCreatedTask /* 任务句柄,就是任务的任务控制块 */
)
实现动态创建任务流程
用起来只需这三步:
1、将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
2、定义函数入口参数
3、编写任务函数
此函数创建的任务会立刻进入就绪态,由任务调度器调度运行
动态创建任务函数内部实现:
1、申请堆栈内存&任务控制块内存
2、TCB结构体成员赋值
3、添加新任务到就绪列表中
任务控制块结构体成员介绍
typedef struct tskTaskControlBlock
{
volatile StackType_t * pxTopOfStack; /* 任务栈栈顶,必须为TCB的第一个成员 */
ListItem_t xStateListItem; /* 任务状态列表项 */
ListItem_t xEventListItem; /* 任务事件列表项 */
UBaseType_t uxPriority; /* 任务优先级,数值越大,优先级越大 */
StackType_t * pxStack; /* 任务栈起始地址 */
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任务名字 */
…
省略很多条件编译的成员
} tskTCB;
任务栈栈顶,在任务切换时的任务上下文保存、任务恢复息息相关
注意:每个任务都有属于自己的任务控制块,类似身份证
静态创建任务函数
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 /* 任务控制块指针,由用户分配 */
);
静态创建任务使用流程
用起来只需这五步:
1、需将宏configSUPPORT_STATIC_ALLOCATION 配置为 1
2、定义空闲任务&定时器任务的任务堆栈及TCB
3、实现两个接口函数
vApplicationGetIdleTaskMemory( ) //空闲任务内存分配
vApplicationGetTimerTaskMemory ( ) //软件定时器内存分配(可选,FreeRTOSconfig.h里面没有使能软件定时器的话,就不需要)
4、定义函数入口参数
5、编写任务函数
此函数创建的任务会立刻进入就绪态,由任务调度器调度运行
静态创建内部实现:
1、TCB结构体成员赋值
2、添加新任务到就绪列表中
任务删除函数
void vTaskDelete(TaskHandle_t xTaskToDelete);
用于删除已被创建的任务
被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中移除
注意:
1、当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
2、当在当前任务时执行任务删除函数,需先添加到等待删除列表,内存释放将在空闲任务执行,空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将导致内存泄露。
删除任务流程
用起来只要这两步:
1、使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
2、入口参数输入需要删除的任务句柄(NULL代表删除本身)
内部实现过程:
1、获取所要删除任务的控制块
通过传入的任务句柄,判断所需要删除哪个任务,NULL代表删除自身
2、将被删除任务,移除所在列表
将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表
3、判断所需要删除的任务
删除任务自身,需先添加到等待删除列表,内存释放将在空闲任务执行
删除其他任务,释放内存,任务数量--
4、更新下个任务的阻塞时间
更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务