2025最新超详细FreeRTOS入门教程:第三章 FreeRTOS任务管理

摘要

在前两章中,我们完成了 FreeRTOS 的移植 并学习了 任务的创建。然而,任务并不仅仅是“创建—运行—结束”,而是需要在运行过程中进行 挂起、恢复、删除、优先级调整 等管理操作。
本章将深入讲解 任务管理机制,帮助你在实际项目中灵活调度任务。

2025最新超详细FreeRTOS入门教程


一、任务管理的意义

在嵌入式系统中,不同任务往往具有不同的重要性和运行频率:

  • 高优先级任务:实时响应外部中断(如传感器读取)
  • 低优先级任务:后台维护(如数据记录)
  • 临时任务:某些任务运行完即可删除

因此我们需要:

  • 挂起/恢复:临时冻结或启用任务
  • 删除:释放任务资源
  • 修改优先级:动态调整任务的重要性
任务创建
运行中
挂起任务 vTaskSuspend
恢复任务 vTaskResume
删除任务 vTaskDelete
调整优先级 vTaskPrioritySet

二、任务管理 API

1. 挂起与恢复任务

void vTaskSuspend(TaskHandle_t xTaskToSuspend);
void vTaskResume(TaskHandle_t xTaskToResume);
  • vTaskSuspend(NULL):挂起当前任务
  • vTaskResume(xHandle):恢复指定任务

2. 删除任务

void vTaskDelete(TaskHandle_t xTaskToDelete);
  • 删除后释放任务栈和控制块(TCB)
  • 若删除自己(传入 NULL),需确保系统还有其他任务运行

3. 修改优先级

void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority);
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask);
  • 可动态调整任务优先级
  • uxTaskPriorityGet() 获取当前优先级

4. 查询任务状态

eTaskState eTaskGetState(TaskHandle_t xTask);

任务可能的状态:

  • 运行态 Running
  • 就绪态 Ready
  • 阻塞态 Blocked
  • 挂起态 Suspended
  • 删除态 Deleted

三、任务管理实例

示例:两个任务,控制 LED 与串口

#include "FreeRTOS.h"
#include "task.h"

TaskHandle_t xHandleLED, xHandleUART;

void vTaskLED(void *pvParameters)
{
    while(1)
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        vTaskDelay(500);
    }
}

void vTaskUART(void *pvParameters)
{
    int count = 0;
    while(1)
    {
        printf("UART Task Running: %d\n", count++);
        if(count == 5)
        {
            printf("挂起LED任务\n");
            vTaskSuspend(xHandleLED);
        }
        if(count == 10)
        {
            printf("恢复LED任务\n");
            vTaskResume(xHandleLED);
        }
        vTaskDelay(1000);
    }
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();

    xTaskCreate(vTaskLED, "LED", 128, NULL, 2, &xHandleLED);
    xTaskCreate(vTaskUART, "UART", 128, NULL, 1, &xHandleUART);

    vTaskStartScheduler();
    while(1) {}
}

运行结果

  • 前 5 秒:LED 闪烁 & UART 打印
  • 5~10 秒:LED 任务被挂起,停止闪烁
  • 10 秒后:LED 任务恢复,继续闪烁

四、任务状态转移

被调度
vTaskDelay
Tick 超时
vTaskSuspend
vTaskResume
vTaskDelete
Ready
Running
Blocked
Suspended
Deleted

五、调试任务管理

FreeRTOS 提供一些辅助函数:

vTaskList(char *pcWriteBuffer);
vTaskGetRunTimeStats(char *pcWriteBuffer);
  • vTaskList():打印任务状态表格
  • vTaskGetRunTimeStats():统计 CPU 占用率(需配置 configGENERATE_RUN_TIME_STATS

示例输出:

任务名 状态 优先级 剩余栈 任务号
LED R 2 100 1
UART R 1 120 2
IDLE R 0 150 3

六、常见问题与解决方法

问题 可能原因 解决方法
删除任务后系统异常 删除了当前任务,且无其他任务运行 确保有 Idle Task 或后台任务
修改优先级无效 新优先级等于旧值 检查 configMAX_PRIORITIES
恢复任务无反应 任务不是挂起状态 使用 eTaskGetState() 查询状态
栈溢出报错 栈太小 增大 usStackDepth 或开启溢出检测

七、经验总结

📌 开发建议

  1. 不要频繁创建/删除任务,最好复用已有任务
  2. 建议通过 事件/队列 来通知任务挂起/恢复,而不是直接调用 API
  3. 合理分配优先级:高优先级任务要“短小精悍”,避免占用 CPU 太久
  4. 使用 vTaskList() 定期检查任务状态,避免死任务

八、总结

通过本章学习,你已经掌握:

  • 使用 vTaskSuspend()vTaskResume() 挂起/恢复任务
  • 使用 vTaskDelete() 删除任务
  • 使用 vTaskPrioritySet() 动态调整优先级
  • 使用 eTaskGetState() 查询任务状态

任务管理是 RTOS 的灵魂,它让系统变得灵活、可控,为后续的 消息队列与同步机制 奠定了基础。


👉 下一章:2025最新超详细FreeRTOS入门教程:第四章 FreeRTOS消息队列 ——将介绍任务之间如何通过消息队列通信。


🔗 FreeRTOS专栏


Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐