单片机基础核心知识点汇总(三十八)

目录

前言

一、调度器到底做什么

[二、FreeRTOS 四大任务状态](#二、FreeRTOS 四大任务状态)

[1、运行态 Running:](#1、运行态 Running:)

[2、就绪态 Ready:](#2、就绪态 Ready:)

[3、阻塞态 Blocked:](#3、阻塞态 Blocked:)

[4、挂起态 Suspended:](#4、挂起态 Suspended:)

三、优先级抢占机制

四、时间片轮转机制

五、空闲任务是什么

六、工程实战现象总结

[1、高优先级任务 while 循环无延时。](#1、高优先级任务 while 循环无延时。)

2、同优先级任务之间互不交替执行。

[3、任务调用 vTaskDelay 之后 CPU 占用率没有降下来。](#3、任务调用 vTaskDelay 之后 CPU 占用率没有降下来。)

4、任务挂起之后,系统好像整体卡住。


前言

本篇重点剖析 FreeRTOS 内核调度逻辑:四大任务状态切换、优先级抢占机制、时间片轮转以及空闲任务。把这一块理解透彻之后再去学习队列、信号量,才能够真正处理多任务同步互斥带来的各类工程问题。

一、调度器到底做什么

FreeRTOS 调度器就是操作系统内核里负责挑选任务的模块。

单片机是单核 CPU,同一时刻只能够执行一份任务代码。调度器不断从就绪任务列表选出最合适的任务交给 CPU 执行。整体遵循两条核心规则:高优先级任务优先执行;同优先级就绪任务开启时间片轮转。

这里有一个很重要误区:多任务并不是真正物理并行运行。单核 MCU 只是高速来回切换任务,切换速度极快,给人的感官效果好像多个任务同时跑。

二、FreeRTOS 四大任务状态

1、运行态 Running:

任务此刻占有 CPU 资源,正在执行自身任务函数。单核单片机任意时间点最多只能有一个任务处于运行态。一旦发生任务切换,当前任务立刻退出运行态。

2、就绪态 Ready:

任务运行条件全部满足,可以随时投入运行,但是此刻 CPU 正在运行另一个优先级更高的任务。任务万事俱备,只等待调度器选中自己。新创建出来的任务默认进入就绪态。

3、阻塞态 Blocked:

任务主动放弃 CPU 进入等待状态,最典型场景就是调用 vTaskDelay 延时。处于阻塞态的任务不再消耗 CPU 时间,调度器直接跳过该任务,转而执行其它就绪任务。新手高频踩坑:任务内部使用 for 循环空延时等待,而不是 vTaskDelay,任务会一直停留在就绪态,死死占用 CPU 不放。

4、挂起态 Suspended:

调用 vTaskSuspend 把任务挂起。挂起之后任务直接停止,不会参与调度,哪怕没有任何延时,也得不到 CPU 执行机会,需要调用 vTaskResume 恢复才可以重新参与调度。
简单梳理状态流转:新建任务→就绪态;调度器选中→切换为运行态;调用延时 / 等待信号量→进入阻塞;延时结束回到就绪;调用挂起函数进入挂起;解除挂起回到就绪。

三、优先级抢占机制

FreeRTOS 默认开启优先级抢占。只要出现一个更高优先级任务变为就绪态,调度器立刻发生任务切换,暂停当前正在跑的低优先级任务,立刻执行高优先级任务。

举个工程例子:任务 A 优先级 2 正在运行,此刻任务 B 优先级 3 解除延时进入就绪,系统马上抢占 CPU,任务 B 开始运行。

这里一个非常常见工程坑:高优先级任务如果一直处于就绪态,永远不会让出 CPU,低优先级任务会彻底饿死,永远得不到执行机会。比如高优先级任务 while 循环里面没有 vTaskDelay,不停空跑,低优先级任务完全无法运行。很多人遇到优先级失效,实际就是发生任务饿死现象。

四、时间片轮转机制

抢占模式下,如果多个任务拥有完全相同优先级,就会启用时间片轮转。

每个任务分配固定长度时间片,任务用完自己时间片之后,即便还没有做完事情,也要让出 CPU,交给同优先级下其它就绪任务执行。

注意配置项 configUSE_TIME_SLICING,如果关闭这个宏,同优先级任务就不会做时间片轮转,一旦某个同优先级任务拿到 CPU 就会一直跑下去。实际项目一般保持打开。

时间片不等于延时,时间片只是分配 CPU 使用时长,任务如果中途进入阻塞态,会直接放弃剩余时间片。

五、空闲任务是什么

系统启动调度器之后会自动创建空闲任务,优先级是 0,也就是整个系统最低优先级。

当所有用户任务全部进入阻塞或者挂起状态,没有其它就绪任务的时候,CPU 就跑空闲任务。

空闲任务有几点工程注意事项:

  1. 千万不要在空闲任务里面做耗时业务逻辑;
  2. 如果开启 configUSE_IDLE_HOOK 空闲钩子函数,钩子函数内部不能调用会造成阻塞的 API,例如 vTaskDelay;空闲钩子里面一旦阻塞,系统行为就异常;
  3. 低功耗场景经常利用空闲钩子,在空闲任务里面进入单片机休眠。

六、工程实战现象总结

1、高优先级任务 while 循环无延时。

  • 后果:一直占用 CPU,低优先级任务彻底饿死。,
  • 解决:合适时机释放 CPU,调用阻塞类 API;

2、同优先级任务之间互不交替执行。

  • 排查方向:检查 configUSE_TIME_SLICING 宏是否打开;

3、任务调用 vTaskDelay 之后 CPU 占用率没有降下来。

  • 排查:确认是 vTaskDelay,不要自己写 for 循环空等待;

4、任务挂起之后,系统好像整体卡住。

  • 排查:确认是否把全部任务都挂起,如果全部任务挂起,系统只会跑空闲任务。
相关推荐
智购科技无人售货机厂家1 小时前
自动售货机物联网平台为什么会出现在线状态不一致?~YH
python·单片机·嵌入式硬件·django·pygame
zhangrelay10 小时前
新版|-|单片机原理与接口技术-2026持续改进优化-从MEGA2560-ESP32与Wokwi到ROS2-Lyrical与具身智能栈
笔记·单片机·嵌入式硬件·学习
comyccccc10 小时前
STM32F103C8T6最小系统板设计全解析学习笔记
单片机·1024程序员节
Industio_触觉智能10 小时前
把NPU检测直接嵌进采集终端|RK3576 AI采集终端全链路拆解教程-下
嵌入式硬件·ai·硬件架构·npu·ai视觉·rk3576·采集终端
en.en..11 小时前
STM32 GPIO ODR 与 BSRR 寄存器完整对比详解
单片机·嵌入式硬件
HQB202614 小时前
EG1182|屹晶微电子 60V 内置高压管异步降压 DC‑DC
嵌入式硬件·硬件工程
LCG米15 小时前
STM32硬件SPI驱动SSD1306 OLED实测:上电黑屏排查、页寻址模式与取模扫描方向陷阱
stm32·单片机·嵌入式硬件·嵌入式
深圳老胡16 小时前
STM32C5A3ZG 网络调试总结:从启动失败到连续 Ping 稳定
笔记·stm32·单片机·代码规范
硅基造物主16 小时前
STM32 从 0 到 1 做智能家居(八):PWM 控制风扇、加热片与 SG90 窗帘
stm32·嵌入式硬件·智能家居·hal库·pwm
简单电磁炮16 小时前
关于adc采集
stm32·单片机