FreeRTOS 任务管理核心功能

1. 任务的创建

  • 函数原型

    BaseType_t xTaskCreate(
        TaskFunction_t pxTaskCode,      // 任务函数指针
        const char * const pcName,     // 任务名称(唯一性)
        configSTACK_DEPTH_TYPE usStackDepth, // 栈深度(单位:字)
        void *pvParameters,            // 任务参数
        UBaseType_t uxPriority,        // 优先级(0~configMAX_PRIORITIES-1)
        TaskHandle_t *pxCreatedTask    // 返回任务句柄
        );
    
  • 关键注意事项

    • 任务函数必须是无限循环(不可退出),结束时需调用 vTaskDelete(NULL) 删除自身。
    • 任务名称需唯一,便于调试和跟踪。
    • ⚠️ 栈深度单位是字(Word),需根据局部变量/调用深度精确计算,避免溢出。

2. 任务的删除

  • 函数原型:​void vTaskDelete(TaskHandle_t xTask); // 目标任务的句柄

  • 关键注意事项

    • 🔄 删除自身:在任务函数内调用 vTaskDelete(NULL)
    • 确保任务非阻塞:删除前需确认任务未持有锁/未等待资源,否则可能引发死锁。
    • 句柄不会自动置空:删除后需手动将句柄设为 NULL,防止野指针。

3. 任务的挂起与恢复

  • 函数原型

    void vTaskSuspend(TaskHandle_t xTaskToSuspend);  // 挂起指定任务
    void vTaskResume(TaskHandle_t xTaskToResume);    // 恢复指定任务
    
  • 关键注意事项

    • ⚠️ 资源安全:挂起前确保任务未占用共享资源(如队列、信号量)。
    • 🔄 调度影响:恢复的任务若优先级 ≥ 当前任务,会立即抢占 CPU。
    • 阻塞状态:挂起时任务若在等待事件(如延时),恢复后需重新等待。

4. 任务的优先级管理

  • 设置优先级函数

    BaseType_t xTaskPrioritySet(
        TaskHandle_t xTask,           // 目标任务句柄
        UBaseType_t uxNewPriority     // 新优先级
        );
    
  • 调度规则

    • 🔢 优先级范围0(最低)到 configMAX_PRIORITIES-1(最高)。
    • 🔄 同优先级调度:采用时间片轮转(FIFO),每个任务执行固定时长。
    • 动态调整:优先级可运行时修改,适用于自适应系统。

总结与最佳实践

操作 核心要点
创建任务 栈深度精确计算、任务函数无限循环、名称唯一化
删除任务 优先用 vTaskDelete(NULL) 删除自身;清理任务占用的资源(内存、外设)
挂起/恢复 避免在临界区挂起任务;恢复高优先级任务会触发调度
优先级设置 不超过 configMAX_PRIORITIES-1;同优先级任务公平调度

💡 扩展建议

  • 使用 xTaskCreateStatic() 替代 xTaskCreate() 可避免动态内存分配(适用于无堆环境)。
  • 优先级反转问题可通过互斥量(Mutex)的优先级继承机制解决。
  • 调试时利用 pcTaskGetName()uxTaskPriorityGet() 跟踪任务状态。