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

目录

前言

一、调度器到底做什么

[二、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 小时前
商业航天星载数据管理单元的存储容错与接口集成方案研究
嵌入式硬件·架构·ecc·商业航天·抗辐射
崇山峻岭之间2 小时前
HC32F460PETB的PH2的EVENTOUT
单片机
恒锐丰科技林技术员2 小时前
EG2203:一款高性价比 600V 半桥驱动芯片
经验分享·嵌入式硬件·硬件工程
斑马1392 小时前
单片机学习笔记(二)——UART串口与DS18B20
单片机
新晨单片机设计3 小时前
S018A-基于STM32单片机脉搏计(光电对管)【Proteus仿真+Keil程序+原理图】
stm32·单片机·嵌入式硬件·proteus
HRTOS3 小时前
HRTOS Debug:8051实时操作系统资源状态监控与分析
单片机·嵌入式硬件·51单片机
李永奉4 小时前
中科蓝讯SDK开发-耳机项目功耗问题排查教程
c语言·开发语言·嵌入式硬件·物联网·智能手机
崇山峻岭之间4 小时前
HC32F460PETB的PH2的EMB_IN4
单片机
Rocktech_ruixun4 小时前
机器人集群调度方案硬件如何选型?瑞迅科技RK3588/3576/3568分级方案解析
人工智能·嵌入式硬件·机器人·边缘计算