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

【FreeRTOS#1】多任务处理任务调度器任务状态

一、多任务处理        

        内核是操作系统的核心组件。学过ARM架构的朋友们都很清楚,STM32微控制器中只有一个内核。例如,在F1系列架构中,Cortex-M3内核通过D-bus和Sys-bus直接访问总线矩阵,通过ICode访问Flash闪存,其中没有其他核心辅助这些过程,换句话说STM32是32位单核微控制器

        实时操作系统中的每个程序都是受其控制的任务,而能同时执行多个任务的操作系统叫做多任务操作系统

             

        多任务操作系统对我们的开发过程具有简化设计流程的意义:

(1)操作系统的多任务处理和任务间通信允许将复杂的应用程序分为一组更小更容易管理的任务

(2)通过程序分割,能够更容易测试,分解工作和复用代码

(3)免去了开发者复杂的时序排序,由系统负责进行

        在嵌入式实时操作系统中,多任务是以并发的方式进行的。这里区别并行并发。

        在多核系统中,通过一个核心负责一个任务,核心之间各负责各自不干扰的方式实现同时处理多个任务的过程叫做并行

        

        上图为并行过程,每一个颜色对应的任务就是一个核心负责的。

        在嵌入式系统中,在某种调度规则下使单核对多任务分时复用的过程是并发过程。有些纯软件领域的人也会称这个过程为 伪并发。为什么叫做伪并发?请看下图:

        

        在并发全过程中,只能使用一个内核,这意味着我们只可以使用分时复用的方法分配多任务,一定不可能出现一个时间段tn-1到tn内,存在两个任务正在执行。

二、任务调度器

        刚才讲了多任务的概念,那么我们的FreeRTOS是如何调度多任务的呢?

        FreeRTOS系统中存在一个多任务调度器。

        一般情况下,FreeRTOS默认使用抢占式调度,同等优先级时使用时间片轮询调度。

        抢占式调度简单来说就是,当Pr0、Pr1、Pr2 三个任务都已准备完毕时,我们优先调度Pr0。再或者Pr2执行到一半时,Pr1突然准备好了,则Pr1进行抢占运行,以此类推。

        时间片轮询调度就是,若TSK1,TSK2,TSK3同优先级,按照嵌入式程序中常说的轮询顺序,在一个规定的时间片Tc下按照轮询顺序进行调度。

        接下来我们分析几个示意图来理解这两个模式,

        

        上图中,最初TSK2和TSK3都尚未准备完毕,只能先运行优先级最低的TSK1。当TSK2准备完毕时,立即抢占TSK1,接着TSK3准备完毕以及抢占。接着,TSK3因为遇到了delay等阻塞类函数,进入了阻塞状态,把执行权交给TSK2,等TSK3恢复,再次抢占。

        这就很像抢厕所的例子,某个公司卫生间只有一个马桶,而普工、经理、老板都在某一刻想上大号。普工先赶到卫生间,不知道是否释放完毕,经理就急着敲门让他出来,然后自己进去。

紧接着老板也赶了过来,让拉一半的经理出来,老板自己进去。老板发现自己好像有点便秘,决定先出去缓一缓再继续,经理就进去了......

        

        接下来就是时间片轮询访问了,这里需要注意的是:一般情况下,每一个Tc触发一次SysTick中断,但如果程序提前结束,则提前跳入下一个Tc。

三、任务状态

        FreeRTOS系统中有四种任务状态

(1)运行态:指的就是任务在正常运行的状态(单核系统只能有一个任务处在运行态)

(2)就绪态: 已准备好运行,但被更高优先级任务抢占的任务状态

(3)阻塞态:遇到了Delay/外部事件,处于等待状态

(4)挂起态:调用了suspend函数,强制使任务进入暂停状态

        四个状态的转换关系如下图所示,

        

        根据上图需要明确一个规律,只有就绪态能直接转换为运行态,其他状态想要进入运行态,必须先转换为就绪态。

        在FreeRTOS系统中,任务状态是以列表形式存储在内存中的,这些列表被我们称为任务状态列表。

        其实,这里所说的列表也是以链表形式实现的。

        1. 就绪列表 pxReadyTasksLists [x], x代表抢占优先级

        2. 阻塞列表 pxDelayedTaskList

        3. 挂起列表 pxSuspendedTaskList

       在32位嵌入式系统中,存在一个32位的寄存器用于代表0-31的优先级。当某一位为1,则就绪列表对应元素就有任务存在,底层算法中用此寄存器加快我们的遍历速度。

        下图拿挂起列表举例,

                                    

        需要注意的是,当多个同优先级的任务进入进入就绪/暂态/阻塞时,列表中的一个结点需要存储多个任务。

        调度器总是在就绪表中选高优先级的出列。

http://www.lqws.cn/news/109495.html

相关文章:

  • 【计算机网络 第8版】谢希仁编著 第六章应用层 题型总结1 编码
  • 队列的讲解:C++队列的使用
  • C++ set数据插入、set数据查找、set数据删除、set数据统计、set排序规则、代码练习1、2
  • 6月2日day43打卡
  • 【Python进阶】元类编程
  • 基于c++面向对象的设计(下)
  • 亚马逊Woot提报常见问题第一弹
  • C#基础:使用线程池执行并行任务
  • 蓝绿部署解析
  • 【leetcode-两数之和】
  • 笔记本电脑开机无线网卡自动禁用问题
  • 开源模型应用落地-OpenAI Agents SDK-集成Qwen3-8B(一)
  • 【北邮 操作系统】第十三章 I/O系统
  • 推荐算法八股
  • git clone报错:SSL certificate problem: unable to get local issuer certificate
  • 金融中的线性优化:投资组合分配与求解器 - Part 2
  • 【大模型】ChatGLM训练框架
  • R1-Searcher++新突破!强化学习如何赋能大模型动态知识获取?
  • 产品更新丨谷云科技ETLCloud 3.9.3 版本发布
  • Qiskit:量子计算模拟器
  • 深入理解汇编语言中的顺序与分支结构
  • 19-项目部署(Linux)
  • 新德通科技:以创新驱动光通信一体化发展,赋能全球智能互联
  • CAMEL-AI开源自动化任务执行助手OWL一键整合包下载
  • 依赖注入-@Resource和@Autowired
  • Java并发编程实战 Day 5:线程池原理与使用
  • EMQX 社区版单机和集群部署
  • HCIP(BGP综合实验)
  • 学习STC51单片机26(芯片为STC89C52RCRC)
  • 通过阿里云 DashScope API 调用通义千问