FreeRTOS调度器:抢占与轮转机制

📅 发布时间:2026/7/12 14:36:28 👁️ 浏览次数:
FreeRTOS调度器:抢占与轮转机制
关注星标公众号不错过精彩内容来源 | 嵌入式大杂烩很多工作多年的嵌入式攻城狮都没明白FreeRTOS 调度器的原理。你要明白调度器是整个 RTOS 的核心决定谁在跑、什么时候换人。今天就来展开说说1. FreeRTOS调度器调度器持续监控所有任务状态就绪 / 运行 / 阻塞从就绪链表中选优先级最高的任务占用 CPU状态变化时触发切换。FreeRTOS 默认两种策略并行工作抢占式调度不同优先级之间高优先级随时抢占不管低优先级跑没跑完时间片轮转同优先级之间每人轮流跑一个时间片默认 1ms核心原则优先级高于时间片。这两种行为由FreeRTOSConfig.h中的两个宏独立控制/* FreeRTOSConfig.h */ #define configUSE_PREEMPTION 1 /* 1抢占式0合作式任务必须主动让步 */ #define configUSE_TIME_SLICING 1 /* 1同优先级时间片轮转0关闭轮转 */两个宏都开启才是默认的抢占 时间片模式关掉configUSE_PREEMPTION则退化为合作式调度任务必须调用taskYIELD()才切换。2. 时钟节拍SysTickSysTick 是调度器的心跳默认 1000Hz每 1ms 中断一次。每次中断主要做两件事tick 计数 1 并检查阻塞任务然后决定是否需要上下文切换切换xTaskIncrementTick()内部除了唤醒延时到期任务还包含时间片轮转判断逻辑——如果当前优先级就绪链表里还有其他任务则返回pdTRUE触发切换这段代码说明时间片轮转不是一个独立机制它内嵌在xTaskIncrementTick()里每次 SysTick 中断都会顺带判断。3. 抢占式调度3.1 运行流程假设系统中有3个任务优先级TaskA高优先级3、TaskB中优先级2、TaskC低优先级13.2 调度触发时机调度触发点/调度点说明SysTick 中断最常见每 1ms 检查一次任务主动阻塞vTaskDelay()、xQueueReceive()等任务创建 / 删除 / 改优先级状态变化重新调度ISR 中唤醒高优先级任务中断退出后触发在 ISR 里唤醒任务后需用portYIELD_FROM_ISR()通知调度器不然即便唤醒了高优先级任务也要等下一个 SysTick 才切换3.3 核心源码vTaskSwitchContext()的核心是taskSELECT_HIGHEST_PRIORITY_TASK()宏展开后等效逻辑如下vTaskStartScheduler()启动时做四件事创建空闲任务 → 关中断 → 置xSchedulerRunning pdTRUE→ 调用xPortStartScheduler()内部启动 SysTick 并切换到第一个任务。空闲任务不可缺所有用户任务阻塞时 CPU 有任务可跑同时负责回收被删除任务的 TCB 和栈资源。4. 时间片轮转4.1 运行流程同优先级任务按就绪链表顺序轮流跑每人一个时间片用完切下一个4.2 配置与注意事项#define configTICK_RATE_HZ 1000UL /* 时间片 1ms改成 500 则为 2ms */ /* 延时必须用宏换算不能写死 tick 数 */ vTaskDelay(pdMS_TO_TICKS(100));时间片大小的取舍太小 → 切换频繁上下文保存/恢复的 CPU 开销上升太大 → 同优先级任务响应延迟增大按实际场景平衡。5. 上下文切换无论哪种调度触发最终都走上下文切换三步完成PendSV 优先级设为最低目的是让所有业务中断先处理完再做任务切换不影响中断实时性。PendSV_Handler 汇编实现的核心逻辑ARM Cortex-M3 精简版6. 常见QAQ抢占式调度和时间片轮转的区别A抢占式针对不同优先级高优先级随时抢时间片轮转针对同优先级按时间片顺序切换。两者同时工作优先级优先。Q为什么上下文切换用 PendSV 而不直接在 SysTick 里切ASysTick 优先级比外部中断高若直接切换会打断正在处理的中断。PendSV 优先级最低所有中断处理完后才执行切换保证中断实时性。Q空闲任务有什么用能删掉吗A不能删。空闲任务负责回收被删除任务的 TCB 和栈内存所有用户任务全部阻塞时 CPU 也有任务可跑避免调度器无任务可选。7. 常见问题坑1改了 configTICK_RATE_HZ延时写死 tick 数频率从 1000Hz 改成 500HzvTaskDelay(1000)实际延时变 2 秒。统一换成pdMS_TO_TICKS()即可避免。坑2高优先级任务死循环不让步高优先级任务循环体没有任何阻塞调用低优先级任务永远抢不到 CPU系统假死。高优先级任务循环里需要加阻塞操作如vTaskDelay主动释放低优先级任务有机会运行坑3同优先级任务操作共享资源时间片轮转是轮流任意时刻只有一个任务在跑共享资源照样需要加互斥锁别因为优先级一样就省掉保护。你在项目里遇到过调度相关的问题吗评论区聊聊。------------END------------基于MCU的冰箱压缩机控制方案免费测评并赠送Cortex-M23开发板解锁嵌入式开发新技能部分元器件涨价近10倍小公司最担心什么