当前位置: 首页 > news >正文

Free RTOS:任务状态,任务管理与调度理论

目录

1.任务状态

1.1 FreeRTOS的任务状态:

1.2 阻塞状态(Blocked)

1.3 暂停状态(Suspended)

原型如下:

1.4 就绪状态(Ready)

1.5 完整的状态转换图

1.6 代码

2.任务管理与调度理论

2.1 调度

2.2 FreeRTOS调度

STM32CubeMX

FreeRTOS源码

代码理解图(同优先级的任务)

之后FreeRTOS系统里面有一个Tick中断,1ms一次中断

理解图

代码理解图(不同优先级的任务)

3.空闲任务

3.1 空闲任务的特点:

3.2 空闲任务(Idle 任务)的作用

一个场景

3.3 空闲任务不够

4.Delay 函数

4.1 两个 Delay 函数:

这 2 个函数原型如下:

4.2 vTaskDelay原理:

例如vTaskDelay(5)

例子,假设函数A第一次运行1ms,第二次运行10ms,第三次运行5ms,假设1个Tick为1ms

4.3 vTaskDelayUntil原理:

例子,假设函数A第一次运行1ms,第二次运行10ms,第三次运行5ms,假设1个Tick为1ms


1.任务状态

代码在09_task_suspend里

这个代码相较于08_task_priority添加音乐暂停/恢复功能

1.1 FreeRTOS的任务状态:

运行(Runing)

非运行(Not Running)

然后非运行状态分为三种:

阻塞状态(Blocked)

暂停状态(Suspended)

就绪状态(Ready)

1.2 阻塞状态(Blocked)

在日常生活的例子中,母亲在电脑前跟同事沟通时,如果同事一直没回复,那么母亲的工作就被卡住了、被堵住了、处于阻塞状态(Blocked)。重点在于:母亲在等待

阻塞状态会将程序一直卡在一个地方等待,如果有设置等待时间,比如超时时间到达了这个时间就会结束阻塞状态

1.3 暂停状态(Suspended)

在日常生活的例子中,母亲正在电脑前跟同事沟通,母亲可以暂停:

好烦啊,我暂停一会

领导说:你暂停一下

当前执行的任务调用vTaskSuspend函数让自己暂停,或是其他任务调用vTaskSuspend函数让当前运行的函任务暂停

原型如下:

vTaskResume恢复函数,让暂停的任务从暂停的位置开始运作

1.4 就绪状态(Ready)

这个任务完全准备好了,随时可以运行:只是还轮不到它。这时,它就处于就绪态(Ready)

当任务被创建出来时就进入了就绪状态了

1.5 完整的状态转换图

1.6 代码


2.任务管理与调度理论

优先级、链表管理、任务切换、tick

空闲任务:代码在10_idle_task里

2.1 调度

相同优先级的任务轮流运行

最高优先级的任务优先级运行

高优先级的任务未执行完,低优先级的任务无法运行

一旦高优先级任务处于就绪状态,马上就会运行

最高优先级的任务有多个会轮流运行

2.2 FreeRTOS调度

STM32CubeMX

FreeRTOS源码

代码理解图(同优先级的任务)

当前的两个任务的优先级为24且同级,一个优先级可以有多个任务

创建完这三个任务,之后创建一个优先级为0的空闲任务,然后就启动调度器

在创建第一个任务的时候会先放到对于优先级的链表中的就绪链表中,有一个全局指针(pxCurrentTCB),然后,这个全局指针会在同优先级的链表中,继续指向后续创建的任务直至最后一个创建的任务,当真正启动调度器的时候最在全局指针指向的任务开始

所以,最后创建的任务反而最先开始执行

之后FreeRTOS系统里面有一个Tick中断,1ms一次中断

在Tick中断里会执行以下

1.计时累加,作为时钟基准

2.发起一次调度,遍历ReadyTasksLists从高优先级到低优先级,空链表就下一个,找到第一个非空的链表,把全局指针(pxCurrentTCB)指向下一个任务(最开始创建的任务)

计时累加达到1ms时,再次进行计时累加,再发一次任务调度,遍历ReadyTasksLists从高优先级到低优先级,找到非空的链表,把全局指针(pxCurrentTCB)指向当前任务的下一个任务

循环往复如此

理解图

代码理解图(不同优先级的任务)

假设正在进行默认的任务,优先级为24,Tick中断为1ms,在还没到1ms的时候,有一个优先级25的任务C创建了,那么任务C会在就绪链表ReadyTasksLists中里立马执行,然后,任务C里面又有一个等待函数为2个Tick

这个时候任务C会从就绪状态变为阻塞状态,从ReadyTasksLists中被移出到DelayTasksLists中,之后,任务的调度会继续,会调度默认任务的下一个任务A,Tick中断又到了继续进行调度执行任务B,这个时候2个Tick了,那么这个时候的Tick中断相比于之前的Tick中断会多一个过程判断任务C是否到了时间然后从DelayTasksLists移出到ReadyTasksLists,任务C从阻塞状态变为就绪状态,之后立马执行任务C

如果任务C还调用了暂停函数vTaskSuspend,任务C从就绪状态或阻塞状态进入了暂停状态,那么这个时候任务C不论是在ReadyTasksLists还是在DelayTasksLists,都会进入xSuspendedTaskLists,只要任务C调用了恢复函数vTaskResume,才会从xSuspendedTaskLists进入ReadyTasksLists,从暂停状态进入就绪状态,之后立马执行任务C


3.空闲任务

3.1 空闲任务的特点:

空闲任务优先级为 0:它不能阻碍用户任务运行

空闲任务要么处于就绪态,要么处于运行态,永远不会阻塞

3.2 空闲任务(Idle 任务)的作用

空闲任务(Idle 任务)的作用之一:释放被删除的任务的内存

一个场景

这个时候想要退出整个程序卡死的状态,就需要使用vTaskDelete函数

自杀:vTaskDelete(NULL),空闲任务收尸,空闲任务释放被删除任务的内存

他杀:vTaskDelete(错误任务的句柄),假设是任务A删除了任务B,那么就是任务A来释放任务B的内存

3.3 空闲任务不够

但是如果ReadyTasksLists有太多任务“自杀”空闲任务就会不够来不及释放这些任务的内存,那么就是造成内存不够分配的现象

就需要良好的编程习惯来防止ReadyTasksLists有太多任务“自杀”的现象

1.事件驱动

2.在需要延时的地方使用FreeRTOS中的内置延时函数vTaskDelay(),不要使用死循环,也就是当前,

vTaskDelay()会使得该任务释放CPU资源,进入DelayTasksLists中,这样ReadyTasksLists中就不会有太多的“自杀任务”,空闲任务就有更多的时间去释放那些没有用到延时函数的任务的内存,简而言之就是让这个任务放弃调度


4.Delay 函数

4.1 两个 Delay 函数:

vTaskDelay:至少等待指定个数的 Tick Interrupt 才能变为就绪状态

vTaskDelayUntil:等待到指定的绝对时刻,才能变为就绪状态

这 2 个函数原型如下:

vTaskDelay和 vTaskDelayUntil都是以Tick为单位

4.2 vTaskDelay原理:

vTaskDelay(n个Tick)

例如vTaskDelay(5)

例子,假设函数A第一次运行1ms,第二次运行10ms,第三次运行5ms,假设1个Tick为1ms

可以发现vTaskDelay延时函数是规定了多少时间延时,就是阻塞函数A多少时间,可见函数A每次运行间隔的时间不是周期的

4.3 vTaskDelayUntil原理:

vTaskDelayUntil(当前计数值,n个Tick),一般要配合

xTaskGetTickCount()函数获取当前计数值

例子,假设函数A第一次运行1ms,第二次运行10ms,第三次运行5ms,假设1个Tick为1ms

可以发现vTaskDelayUntil延时函数是先给当前的计数值,然后根据设定了15个Tick,15个Tick缺多少就补多少,将函数的两次运行时间规定为15个Tick,以实现周期运行函数

http://www.jsqmd.com/news/600488/

相关文章:

  • K-Net (NeurIPS‘2021)语义分割环境配置、K-Net (NeurIPS‘2021)语义分割模型代跑训练、K-Net (NeurIPS‘2021)语义分割模型改进创新K-Net
  • 2026年口碑好的隔音降噪背衬板/保温背衬板/卫生间防水背衬板源头工厂推荐 - 品牌宣传支持者
  • nli-distilroberta-base生产环境:低延迟NLI服务在搜索Query改写中应用
  • 24GB显存利用率优化:OpenClaw长任务链对接Qwen3-14B的7个技巧
  • 2026年4月四川GEO营销优质品牌推荐指南 - 优质品牌商家
  • OpenClaw+Phi-3-mini-128k-instruct自动化测试:3步完成代码审查
  • KNX 协议完整整理(嵌入式 / 楼宇实战版)
  • Python预测家庭用电趋势,高并发内存池(六):释放内存全过程搭建。
  • 互联网产品创新:基于MogFace-large的社交平台智能相册分类功能
  • open 和 with open 的区别
  • 避坑指南:Chrome扩展侧边栏开发中常见的5个问题及解决方案(基于Manifest V3)
  • wsl空间回收步骤
  • 2026年有实力的除虫防治/重庆除虫消杀/除虫杀虫高性价比公司 - 品牌宣传支持者
  • PyCharm与Anaconda环境管理详解:Phi-3-mini-4k-instruct-gguf解决Python包冲突
  • OpenClaw极简部署方案:Qwen3-14b_int4_awq最小化依赖安装
  • Linux命令-nethogs(终端下的网络流量监控工具)
  • AI Infra是什么?
  • 2026金属剪板加工优质厂家推荐指南 高精度多场景适配 - 优质品牌商家
  • Pixel Couplet Gen保姆级教程:Pixel Couplet Gen + WeChat MiniProgram SDK集成
  • 2026年知名的非标PTFE滤袋/PTFE滤袋/针刺毡除尘PTFE滤袋/除尘PTFE滤袋销售厂家推荐 - 品牌宣传支持者
  • 2026年质量好的医用铜管/异形铜管/R410A铜管实力工厂怎么选 - 品牌宣传支持者
  • 2.git-repo部署及新项目创建
  • 2026年比较好的折叠门功能五金/功能五金生产厂家推荐 - 品牌宣传支持者
  • 深度行业洞察:如何科学评估与挑选高品质宠物智能舱?
  • 基于机器学习与深度学习的高光谱图像分类包含3DCNN_SVM、3DCNN_RF、3DCNN_SVM三种。其他的需要可以自己改机器学习 深度学习 卷积神经网络 3DCNN 2DCNN 高光谱
  • UI----1
  • 2026年4月吡咯喹啉醌肽饮推荐指南 - 优质品牌商家
  • 2026铸铁雨篦优质供应商推荐榜 高性价比选型 - 优质品牌商家
  • StructBERT-Large中文复述识别效果展示:中文机器翻译后编辑(MTPE)质量语义评估
  • MiniCPM-V-2_6高可信推理:Object HalBench幻觉率低于GPT-4o实测