跟着正点原子整理了一些笔记
一、任务控制块 TCB(tskTaskControlBlock)
每个任务都有独立 TCB,相当于任务的身份证,内核靠 TCB 管理任务
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;二、动态创建任务xTaskCreate()
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 /* 任务句柄,操作任务的标识 */ );使用步骤(上层调用)
- 宏
configSUPPORT_DYNAMIC_ALLOCATION配置为1 - 定义函数入口参数
- 编写任务函数
函数内部实现
- 申请堆栈内存 & TCB 任务控制块内存
- TCB 结构体成员赋值
- 添加新任务到就绪列表
创建后任务直接进入就绪态,等待调度器调度运行
三、静态创建任务xTaskCreateStatic()
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//TCB任务控制块缓冲区地址 );使用步骤
- 宏
configSUPPORT_STATIC_ALLOCATION配置为1 - 定义空闲任务 & 定时器任务 的任务堆栈及 TCB
- 实现 2 个接口函数:
vApplicationGetIdleTaskMemory()vApplicationGetTimerTaskMemory()
- 定义函数入口参数
- 编写任务函数
内部实现
- TCB 结构体成员赋值
- 添加新任务到就绪列表
对比小结:
·动态:内核自动申请任务控制块内存,简单;内存碎片风险
TaskHandle_t * const pxCreatedTask // 任务句柄,操作任务的标识
·静态:用户预先分配任务控制块内存,无 malloc
StackType_t * const puxStackBuffer //栈缓冲区数组地址
StaticTask_t * const pxTaskBuffer //TCB任务控制块缓冲区地址
四、任务删除vTaskDelete
void vTaskDelete(TaskHandle_t xTaskToDelete);功能
将任务从就绪、阻塞、挂起、事件列表全部移除。
重要注意点
- 参数为
NULL:删除当前正在运行的任务自己 - 内存释放规则:空闲任务负责释放系统分配的内存;用户自己 malloc 申请的内存,必须在任务删除前手动释放,否则内存泄漏!
使用步骤
- 宏
INCLUDE_vTaskDelete配置为1 - 传入任务句柄(NULL 代表删除自身)
内部执行流程
- 根据任务句柄找到待删除任务的 TCB;NULL 代表删自己
- 将任务从所有关联链表(就绪 / 阻塞 / 挂起 / 事件)移除
- 判断任务类型
- 删除自身:加入等待删除列表,内存由空闲任务后续释放
- 删除别的任务:直接释放内存,任务计数 - 1
- 更新下一个任务的阻塞超时时间,防止被删任务刚好是下一个超时任务