没志青年
发布于 2025-06-15 / 53 阅读
0

FreeRTOS 任务管理

FreeRTOS中叫任务,RT-Thread中叫线程,一个东西。

FreeRTOS 是抢占式调度系统,高优先级任务一旦就绪(如被信号量唤醒、延迟到期等),会立即抢占 CPU

任务状态

四种任务状态:运行态、就绪态、阻塞态和挂起态

  • 运行态:任务得到了CPU的使用权,正在执行中。单核处理器的同一时刻,只会有一个任务处于运行态。

  • 就绪态:随时可以执行,但由于相同优先级或更高优先级的任务正在执行,因此在等待。

  • 阻塞态:任务主动延时或等待某些外部事件发生(信号量、任务通知等),当到达延时时间、外部事件发生、阻塞超时后,阻塞态解除,进入就绪态。

  • 挂起态:不再参与任务调度,直到手动恢复。

任务优先级

优先级范围:

#define configMAX_PRIORITIES    10  // 优先级范围:0~

数字越大优先级越高,最小的优先级为0,最高优先级:

(configMAX_PRIORITIES - 1)

修改优先级:vTaskPrioritySet(xHandle, 9);

创建任务

// 动态创建
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,                        // 任务函数指针
                            const char * const pcName,                    // 任务名称
                            const configSTACK_DEPTH_TYPE usStackDepth,    // 任务堆栈大小
                            void * const pvParameters,                    // 传递给任务函数的参数
                            UBaseType_t uxPriority,                       // 任务优先级
                            TaskHandle_t * const pxCreatedTask )          // 任务句柄

// 静态创建
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 )  // 任务控制块

任务中必须有让出 CPU 的动作,否则低优先级的任务无法执行。

注意,堆栈的单位为字 word,1 word = 4 bytes(32位平台)


// 动态创建





// 静态创建


删除任务

只能删除动态方式创建的任务。

xTaskDelete(TaskHandle_t xTaskToDelete);

挂起与恢复

挂起后,任务不再参与任务调度。

vTaskSuspend(TaskHandle_t xTaskToSuspend);     // NULL 表示挂起当前任务

任务恢复:

xTaskResumeAll(TaskHandle_t xTaskToResume);

中断安全函数:

需开启:

#define INCLUDE_xTaskResumeFromISR 1

任务调度控制

开启任务调度

void vTaskStartScheduler(void);

暂停任务调度,当前任务独占CPU

void vTaskSuspendAll(void);

恢复任务调度

BaseType_t xTaskResumeAll(void);

虽然暂停任务调度了,但是中断仍是可用的。

如果在中断程序中通过信号量、队列、任务通知等机制使高优先级的任务就绪,那恢复任务调度时,高优先级的任务会立即抢占当前任务。

特殊任务

空闲任务 IdleTask

启动调度器时系统自动创建,优先级为0,在无其他用户任务运行时执行,确保CPU始终执行,作用:

  • 清理已删除的任务:释放任务栈和任务控制块

  • 低功耗处理(Tickless模式):在空闲任务时暂停时钟节拍

  • 执行用户钩子函数 vApplicationIdleHook

Tickless模式需开启:

#define configUSE_TICKLESS_IDLE    1

用户钩子函数需开启:

#define configUSE_IDLE_HOOK    1
// 在空闲任务中执行的用户代码,不能阻塞!
void vApplicationIdleHook(void) {
   
}

若开启了configSUPPORT_STATIC_ALLOCATION,空闲任务也可以使用静态内存创建,需实现 vApplicationGetIdleTaskMemory()

定时器任务 Timer Service Task

又叫做 Timer Daemon Task

如果在设置中开启了软件定时器,在启动定时器后 FreeRTOS 会自动创建一个定时器任务,可自定义栈大小和优先级。

#define configUSE_TIMERS             1   // 启用定时器服务


#define configTIMER_TASK_PRIORITY    (configMAX_PRIORITIES - 1)     // 最高优先级
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE * 2  // 栈大小
#define configTIMER_QUEUE_LENGTH     10  // 定时器命令队列长度

作用:

  • 调用软件定时器回调函数,就是创建定时器时填的那个参数

  • 清理被删除的定时器

  • 异步处理定时器命令

栈大小、优先级推荐设置?

CPU 占用率查询

评估程序的质量,看它的CPU占用率。

造成CPU占用率过高的因素:

  • 程序本身质量不高

  • CPU 本身性能较弱

  • 硬件故障

freertos提供了一个查询CPU占用率的接口

合理的创建任务