3、FreeRTOS任务管理:任务创建与删除、任务优先级与调度策略、任务状态切换、空闲任务与钩子函数
各位同学,咱们今天聊聊FreeRTOS的任务管理。说实话,任务管理是RTOS的魂。你想想看,一个无人机飞控系统里,要同时处理传感器数据、控制算法、通信协议、电机驱动……如果没有任务管理,这些代码挤在一起,迟早要出乱子。
我在做飞控项目时,早期用过裸机跑循环,后来发现根本扛不住。一个传感器中断来了,另一个任务就被卡死。嗯,从那以后,我彻底转向了RTOS。今天的内容,就是FreeRTOS任务管理的核心。
3.1 任务创建与删除
任务创建,说白了就是告诉FreeRTOS:“嘿,我这里有一段代码,你帮我调度着跑。” 用xTaskCreate()这个API就行。我个人习惯把任务函数写成无限循环,里面放个vTaskDelay(),让出CPU。
// 任务函数原型
void vTaskFunction(void *pvParameters);
// 创建任务
xTaskCreate(
vTaskFunction, // 任务函数指针
"TaskName", // 任务名字(调试用)
configMINIMAL_STACK_SIZE, // 栈深度
NULL, // 参数
tskIDLE_PRIORITY + 1, // 优先级
NULL // 任务句柄(可选)
);
删除任务用vTaskDelete()。注意,任务可以自己删除自己,传NULL就行。我在项目中遇到过一种情况:某个任务初始化失败,直接把自己删了,避免影响其他任务。这个做法很实用。
3.2 任务优先级与调度策略
FreeRTOS支持抢占式调度。优先级高的任务先跑,同优先级的任务轮转。你想想看,无人机飞控里,电机控制任务的优先级肯定比日志打印高。否则电机响应慢了,飞机就翻了。
| 优先级 | 典型任务 | 说明 |
|---|---|---|
| 最高 | 电机控制 | 实时性要求极高,毫秒级响应 |
| 高 | 传感器采集 | IMU、GPS数据,需要及时读取 |
| 中 | 控制算法 | 姿态解算、PID计算 |
| 低 | 日志、通信 | 可以容忍延迟 |
调度策略上,FreeRTOS默认是抢占式。但你可以配置成协作式(时间片轮转)。我个人建议飞控项目用抢占式,因为实时性要求摆在那里。协作式适合那些任务之间互相谦让的场景,但无人机可不会谦让。
3.3 任务状态切换
FreeRTOS的任务有四种状态:运行态、就绪态、阻塞态、挂起态。说白了,就是任务在“干活”、“等着干活”、“睡着了”、“被关禁闭”之间切换。
- 运行态: 当前正在使用CPU的任务。只有一个任务能处于运行态。
- 就绪态: 任务准备好了,但CPU被别的任务占着。等调度器一换,它就上。
- 阻塞态: 任务在等某个事件,比如延时、信号量、队列。这时候它不消耗CPU。
- 挂起态: 任务被
vTaskSuspend()挂起,除非被vTaskResume()唤醒,否则永远不跑。
我在项目中遇到过一个问题:某个传感器任务一直处于阻塞态,因为它的信号量没被释放。排查了半天,发现是另一个任务忘记释放信号量了。嗯,这种问题很隐蔽,调试时一定要看任务状态。
// 查看任务状态(调试用)
TaskStatus_t xTaskDetails;
vTaskGetInfo(xTaskHandle, &xTaskDetails, pdTRUE, eInvalid);
// xTaskDetails.eCurrentState 就是当前状态
3.4 空闲任务与钩子函数
空闲任务是FreeRTOS自动创建的,优先级最低。当所有其他任务都阻塞或挂起时,空闲任务就跑起来了。它主要做两件事:释放被删除任务的栈空间,以及进入低功耗模式。
钩子函数,说白了就是空闲任务里可以插入一段用户代码。你可以在FreeRTOSConfig.h里把configUSE_IDLE_HOOK设为1,然后实现vApplicationIdleHook()。
void vApplicationIdleHook(void)
{
// 这里可以放低功耗代码
// 或者做一些后台清理工作
// 注意:不要阻塞!不要调用可能导致阻塞的API!
}
vTaskDelay()、xQueueReceive()等可能阻塞的API。否则空闲任务会被卡住,系统就崩了。我曾经在钩子里放了个延时,结果整个系统像死机一样,排查了好久才发现。
另外,空闲任务的栈大小可以配置。如果你的钩子函数比较复杂,记得把configMINIMAL_STACK_SIZE调大一点。我一般设成128或256字节,够用就行。
好了,今天的内容就到这里。任务创建与删除、优先级调度、状态切换、空闲任务,这四个点搞明白了,FreeRTOS的任务管理你就掌握了八成。下一章咱们聊聊任务间的同步与通信,那才是真正让飞控系统跑起来的关键。