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占用率的接口