发布时间:2026/7/15 14:51:00
FreeRTOS调度器在做什么?从任务状态机说起 一段代码跑在单片机里和我们平时写PC程序最大的不同是什么不是语法不是编译器——是同时做多件事的方式。PC上开十个窗口操作系统帮你来回切换你感觉不到延迟。但在STM32上一个单核Cortex-M3要同时处理按键扫描、LCD刷新、传感器数据采集和通信协议解析谁来决定这些任务什么时候跑、跑多久、让谁先跑答案是调度器。我们来看FreeRTOS是怎么解决这个问题的。任务不是同时运行而是轮流露脸首先要理解的一个核心概念是在任何单核处理器上某一时刻只有一个任务在执行。所谓多任务不过是调度器在极短的时间内让不同的任务轮流使用CPU。FreeRTOS中的每个任务都有四种状态运行态Running、就绪态Ready、阻塞态Blocked和挂起态Suspended。我们就从这几个状态入手看看调度器到底在忙什么。当系统上电vTaskStartScheduler()被调用后调度器开始工作。它会从所有就绪态的任务中挑一个优先级最高的来执行——这就是运行态。如果这个任务调用了vTaskDelay()或者等待某个队列/信号量它就从运行态转入阻塞态。此时调度器回头扫一眼就绪列表再挑一个当前优先级最高的继续跑。如此循环往复。一个有意思的设计是如果两个任务优先级相同FreeRTOS会使用时间片轮转Round-Robin。每个任务跑一个tick通常1ms时间一到就被强制换下换另一个同优先级的上场。这和我们平时用Linux的CFS调度器的感受不太一样——在FreeRTOS里优先级决定了能不能抢跑而时间片决定了跑多久。谁在驱动这一切Tick中断调度器的每一次决策都需要一个触发器。这个触发器就是SysTick定时器产生的中断。每次tick中断到来FreeRTOS会做几件事- 减少当前任务的时间片计数如果有用时间片轮转- 检查是否有阻塞中的任务已经超时如果有将它们移回就绪列表- 调用vTaskSwitchContext()决定要不要切换任务如果当前运行的是最高优先级的就绪任务那无事发生继续跑。如果刚超时了一个优先级更高的任务那上下文切换就触发当前任务被打断存好寄存器现场让高优先级任务顶上。这里的存寄存器现场非常关键。每次任务切换时FreeRTOS会手动将R0-R12、LR、PC、xPSR等压入当前任务的栈中然后从目标任务的栈里弹出这些寄存器。切换完以后新任务继续执行完全不知道自己刚才被挂起过。一个很多人没注意到的细节Idle任务你一定注意到了一件事如果所有任务都阻塞了谁来跑或者说调度器从就绪列表里挑人如果就绪列表是空的呢FreeRTOS的设计很聪明——它在启动调度器时自动创建了一个优先级为0的Idle任务。这个任务永不阻塞永远处于就绪态唯一的用途是当没有其他任务可以运行的时候让CPU有事可做。Idle任务默认会执行一条wfiWait For Interrupt指令或者空循环具体取决于配置项configIDLE_SHOULD_YIELD_IS_1。一个常见的优化是在Idle任务里喂狗、进入低功耗模式或者做系统级的内务处理比如释放被删除任务的内存。但这里有个陷阱——千万不要把Idle任务的优先级改高。如果你在应用代码中把其他任务也设为优先级0那这些任务会和Idle任务同优先级。由于Idle任务默认配置了允许被同优先级任务抢占configIDLE_SHOULD_YIELD_IS_1它每次都会让出时间片给其他同优先级任务这也意味着它可能很少真正运行到你的内务代码就得不到执行。优先级反转问题讲调度器就绕不开优先级反转。考虑三个任务TaskA优先级3、TaskB优先级2、TaskC优先级1。它们共享一个互斥量保护的资源。场景是这样的TaskC先拿到了互斥量开始访问共享资源。这时TaskA就绪了它优先级更高立刻抢占了TaskC。TaskA也想要同一个互斥量但TaskC还拿着TaskA被阻塞。调度器回头一查TaskB刚好也就绪了。注意——TaskB优先级高于TaskC但低于TaskA它不需要互斥量它就直接跑起来了。结果呢TaskB跑得欢TaskC被TaskB抢占了没法释放互斥量TaskA还在那儿等着。明明是优先级最高的任务反而被最低优先级的任务卡住了。这就是优先级反转。FreeRTOS的互斥量通过优先级继承协议来处理这个问题当高优先级任务被低优先级任务持有的互斥量阻塞时系统会把持有者的优先级暂时提升到与等待任务的优先级相同即TaskC被临时提权到3让TaskC能尽快跑完、释放互斥量。之后TaskC的优先级恢复原值。配置项configUSE_MUTEXES和configUSE_PRIORITY_INHERITANCE需要同时启用才能生效。标准信号量xSemaphoreCreateBinary没有这个机制——只有互斥量才带了优先级继承。如何观察调度器的行为如果你想亲眼看看调度器在做决策最简单的方法是拉一个GPIO在vTaskSwitchContext()里翻转它。用逻辑分析仪或者示波器看这个引脚的波形每次跳变就是一次任务切换。也可以用FreeRTOS的trace功能。配置configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS后vTaskList()和uxTaskGetSystemState()能打印出每个任务的运行时间统计——哪个任务吃了多少CPU一目了然。上次调一个传感器驱动时发现某个任务的CPU占用率莫名奇高用这个一查发现是它在轮询里没有加阻塞延时while(1)里面直接跑空了。加上vTaskDelay(pdMS_TO_TICKS(10))之后占用率从85%降到了3%。你遇过类似的情况吗

相关新闻

2026/7/15 14:51:00

CANN/asc-devkit Conv3D End接口

End 产品支持情况产品 是否支持 Ascend 950PR/Ascend 950DT x Atlas A3 训练系列产品/Atlas A3 推理系列产品 √ Atlas A2 训练系列产品/Atlas A2 推理系列产品 √ Atlas 200I/500 A2 推理产品 x Atlas 推理系列产品AI Core x Atlas 推理系列产品Vector Core x Atlas 训练系列产…

2026/7/15 14:51:00

Three.js 建筑线条教程

建筑线条 Building Line ▶ 在线运行案例 案例合集: 三维可视化功能案例(threehub.cn)开源仓库github地址: https://github.com/z2586300277/three-cesium-examples400个案例代码: 网盘链接 你将学到什么 OrbitControls 相机…

2026/7/15 14:51:00

CANN/asc-devkit三维卷积偏置接口

SetBias 产品支持情况 产品 是否支持 Ascend 950PR/Ascend 950DT x Atlas A3 训练系列产品/Atlas A3 推理系列产品√ Atlas A2 训练系列产品/Atlas A2 推理系列产品√ Atlas 200I/500 A2 推理产品x Atlas 推理系列产品AI Core x Atlas 推理系列产品Vector Core x Atlas 训练系…

2026/7/15 15:41:10

CANN/asc-devkit remove_reference类型特性

remove_reference 产品支持情况产品 是否支持 Ascend 950PR/Ascend 950DT √ Atlas A3 训练系列产品/Atlas A3 推理系列产品 √ Atlas A2 训练系列产品/Atlas A2 推理系列产品 √ Atlas 200I/500 A2 推理产品 x Atlas 推理系列产品AI Core x Atlas 推理系列产品Vector Core x A…

2026/7/15 15:41:10

Spring Boot+Vue+微信小程序全栈电商系统架构设计与实施指南

Spring BootVue微信小程序全栈电商系统架构设计与实施指南 【免费下载链接】litemall 又一个小商城。litemall Spring Boot后端 Vue管理员前端 微信小程序用户前端 Vue用户移动端 项目地址: https://gitcode.com/gh_mirrors/li/litemall 在数字化转型浪潮中&#xf…

2026/7/15 15:41:10

CANN/Ascend C标准库min函数

min 产品支持情况产品 是否支持 Ascend 950PR/Ascend 950DT √ Atlas A3 训练系列产品/Atlas A3 推理系列产品 √ Atlas A2 训练系列产品/Atlas A2 推理系列产品 √ Atlas 200I/500 A2 推理产品 x Atlas 推理系列产品AI Core √ Atlas 推理系列产品Vector Core x Atlas 训练系列…

2026/7/15 15:41:10

从算力到实用性,全方位解析AI 主机选购指南要点

当下AI绘图、自动化办公、代码生成需求持续上涨,不少用户想要一台适配AI运行的小型设备,却不懂分辨产品优劣,一份完整的AI主机选购指南能够大幅降低踩坑概率。翻阅各类迷你主机排行榜、能打游戏的迷你主机性价比排行榜对比多款产品后&#xf…

2026/7/15 15:36:10

计算机毕业设计之jsp鲜花购物商城系统的设计与实现

当今社会已经步入了科学技术进步和经济社会快速发展的新时期,国际信息和学术交流也不断加强,计算机技术对经济社会发展和人民生活改善的影响也日益突出,人类的生存和思考方式也产生了变化。传统鲜花购物商城采取了人工的管理方法,…

2026/7/14 12:47:32

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/14 19:23:19

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/14 18:30:06

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/15 0:08:29

【LINUX】驱动

【LINUX驱动】【字符设备】【中断】【Platform】【网课 设备树】【GPIO】【PINCTRL】【INPUT】【IIC】【SPI】【网络驱动】【屏幕驱动】【一 设备树】【二 内核模块编译】【三 基本驱动框架】【四 Platform总线设备驱动框架】【五 驱动子系统】【六 综合】

2026/7/15 0:08:29

【1982-2026】全国高精度建筑轮廓|村级精度|SHP矢量

🔍 数据简介 本次分享1982-2026年全国村级精度建筑轮廓矢量数据,覆盖全国各省市区县,到村级别精细,为2026年最新实时采集成果,非网传仅60/77个城市的老旧数据。 数据含带高度/不带高度双版本,单体建筑边界精…

2026/7/15 0:08:29

【1975-2026】全国水系水路数据|河流/水库/运河|SHP矢量

🔍 数据简介 本次分享1975-2026年全国高精度水系水路矢量数据,覆盖全国全域,包含河流、水系、水库、运河、湿地、冰川、沟渠等全类别水文要素。 数据集包含双层矢量图层,字段分类清晰、要素齐全,支持2013-2026逐年完整…

2026/7/15 13:36:32

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…