FreeRTOS——任务调度—抢占式,时间片和合作式
以下转载自安富莱电子: http://forum.armfly.com/forum.php
本章教程为大家将介绍 FreeRTOS 操作系统支持的任务调度方式:抢占式,时间片和合作式,这部分
算是 FreeRTOS 操作系统的核心了。 对于初学者来说,要一下子就能够理解这些比较困难,需要多花些时
间把这些基本概念搞清楚,然后阅读下源码,深入理解实现方法。
关于合作式调度器的特别说明
FreeRTOS 支持的调度方式
FreeRTOS 操作系统支持三种调度方式:抢占式调度,时间片调度和合作式调度。 实际应用主要是
抢占式调度和时间片调度,合作式调度用到的很少。
抢占式调度
每个任务都有不同的优先级,任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的 API 函数,
比如 vTaskDelay。
时间片调度
每个任务都有相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式的 API 函数,比如
vTaskDelay,才会执行同优先级任务之间的任务切换。
什么是调度器
简单的说,调度器就是使用相关的调度算法来决定当前需要执行的任务。所有的调度器有一个共同的
特性:
调度器可以区分就绪态任务和挂起任务(由于延迟,信号量等待,邮箱等待,事件组等待等原因而使
得任务被挂起)。
调度器可以选择就绪态中的一个任务,然后激活它(通过执行这个任务)。 当前正在执行的任务是运
行态的任务。
不同调度器之间最大的区别就是如何分配就绪态任务间的完成时间。
嵌入式实时操作系统的核心就是调度器和任务切换,调度器的核心就是调度算法。任务切换的实现在
不同的嵌入式实时操作系统中区别不大,基本相同的硬件内核架构,任务切换也是相似的。调度算法就有
些区别了。下面我们主要了解一下抢占式调度器和时间片调度器。
抢占式调度器基本概念
在实际的应用中,不同的任务需要不同的响应时间。例如,我们在一个应用中需要使用电机,键盘和
LCD 显示。电机比键盘和 LCD 需要更快速的响应,如果我们使用合作式调度器或者时间片调度,那么电
机将无法得到及时的响应,这时抢占式调度是必须的。
如果使用了抢占式调度,最高优先级的任务一旦就绪,总能得到 CPU 的控制权。 比如,当一个运行
着的任务被其它高优先级的任务抢占,当前任务的 CPU 使用权就被剥夺了,或者说被挂起了,那个高优
先级的任务立刻得到了 CPU 的控制权并运行。 又比如,如果中断服务程序使一个高优先级的任务进入就
绪态,中断完成时,被中断的低优先级任务被挂起,优先级高的那个任务开始运行。
使用抢占式调度器,使得最高优先级的任务什么时候可以得到 CPU 的控制权并运行是可知的,同时
使得任务级响应时间得以最优化。
总的来说,学习抢占式调度要掌握的最关键一点是:每个任务都被分配了不同的优先级,抢占式调度
器会获得就绪列表中优先级最高的任务,并运行这个任务。
FreeRTOS 抢占式调度器的实现
如果用户在 FreeRTOS 的配置文件 FreeRTOSConfig.h 中禁止使用时间片调度, 那么每个任务必须配
置不同的优先级。当 FreeRTOS 多任务启动执行后,基本会按照如下的方式去执行:
首先执行的最高优先级的任务 Task1, Task1 会一直运行直到遇到系统阻塞式的 API 函数,比如延迟,
事件标志等待,信号量等待,Task1 任务会被挂起,也就是释放 CPU 的执行权,让低优先级的任务
得到执行。
FreeRTOS 操作系统继续执行任务就绪列表中下一个最高优先级的任务 Task2,Task2 执行过程中有
两种情况:
Task1由于延迟时间到, 接收到信号量消息等方面的原因, 使得 Task1从挂起状态恢复到就绪态,
在抢占式调度器的作用下,Task2 的执行会被 Task1 抢占。
Task2 会一直运行直到遇到系统阻塞式的 API 函数,比如延迟,事件标志等待,信号量等待, Task2
任务会被挂起,继而执行就绪列表中下一个最高优先级的任务。
如果用户创建了多个任务并且采用抢占式调度器的话,基本都是按照上面两条来执行。 根据抢占式调
度器,当前的任务要么被高优先级任务抢占,要么通过调用阻塞式 API 来释放 CPU 使用权让低优先
级任务执行,没有用户任务执行时就执行空闲任务。
运行条件:
这里仅对抢占式调度进行说明。
创建 3 个任务 Task1,Task2 和 Task3。
Task1 的优先级为 1,Task2 的优先级为 2,Task3 的优先级为 3。 FreeRTOS 操作系统是设置的数值
越小任务优先级越低,故 Task3 的优先级最高,Task1 的优先级最低。
此框图是 FreeRTOS 操作系统运行过程中的一部分。
运行过程描述如下:
此时任务 Task1 在运行中,运行过程中由于 Task2 就绪,在抢占式调度器的作用下任务 Task2 抢占
Task1 的执行。 Task2 进入到运行态,Task1 由运行态进入到就绪态。
任务 Task2 在运行中,运行过程中由于 Task3 就绪,在抢占式调度器的作用下任务 Task3 抢占 Task2
的执行。 Task3 进入到运行态,Task2 由运行态进入到就绪态。
任务 Task3 运行过程中调用了阻塞式 API 函数,比如 vTaskDelay,任务 Task3 被挂起,在抢占式调
度器的作用下查找到下一个要执行的最高优先级任务是 Task2,任务 Task2 由就绪态进入到运行态。
任务 Task2 在运行中,运行过程中由于 Task3 再次就绪,在抢占式调度器的作用下任务 Task3 抢占
Task2 的执行。 Task3 进入到运行态,Task2 由运行态进入到就绪态。
上面就是一个简单的不同优先级任务通过抢占式调度进行任务调度和任务切换的过程。
时间片调度器基本概念
在小型的嵌入式 RTOS 中,最常用的的时间片调度算法就是 Round-robin 调度算法。这种调度算法
可以用于抢占式或者合作式的多任务中。另外,时间片调度适合用于不要求任务实时响应的情况。
实现 Round-robin 调度算法需要给同优先级的任务分配一个专门的列表,用于记录当前就绪的任务,
并为每个任务分配一个时间片(也就是需要运行的时间长度,时间片用完了就进行任务切换)。
FreeRTOS 时间片调度器的实现
在 FreeRTOS 操作系统中只有同优先级任务才会使用时间片调度,另外还需要用户在
FreeRTOSConfig.h 文件中使能宏定义:
#define configUSE_TIME_SLICING 1
默认情况下,此宏定义已经在 FreeRTOS.h 文件里面使能了,用户可以不用在 FreeRTOSConfig.h 文
件中再单独使能。
下面我们通过如下的框图来说明一下时间片调度在 FreeRTOS 中的运行过程,让大家有一个形象的认识。
运行条件:
这里仅对时间片调度进行说明。
创建 4 个同优先级任务 Task1,Task2,Task3 和 Task4。
每个任务分配的时间片大小是 5 个系统时钟节拍。
运行过程描述如下:
先运行任务 Task1,运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task2。
任务 Task2 运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task3。
任务 Task3 在运行期间调用了阻塞式 API 函数,调用函数时,虽然 5 个系统时钟节拍的时间片大小
还没有用完,此时依然会通过时间片调度切换到下一个任务 Task4。 (注意,没有用完的时间片不会
再使用,下次任务 Task3 得到执行还是按照 5 个系统时钟节拍运行)
任务 Task4 运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task1。
上面就是一个简单的同优先级任务通过时间片调度进行任务调度和任务切换的过程。
Summary:
时间片调度和抢占式调度我们一般都是开启了的,这样优先级相同时,使用时间片调度,优先级不同时,使用抢占式调度。默认情况下,在freertos.h中使能了时间片调度:
而抢占式调度需要我们用户自己开启,一般在freertosconfig.h中使能:
FreeRTOS——任务调度—抢占式,时间片和合作式的更多相关文章
- RTX——第10章 任务调度-抢占式、时间片和合作式
以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章教程为大家将介绍 RTX 操作系统支持的任务调度方式,抢占式,时间片和合作式,这部分算是RTX 操作 ...
- 使用KEIL C51实现的简单合作式多任务操作系统内核(单片机实现版本)
基于网上网友的代码,自己在单片机上实现, 特此记录分享之. 基于https://blog.csdn.net/yyx112358/article/details/78877523 //使用KEIL C5 ...
- Python的列表推导式,字典推导式,集合推导式使用方法
推导式分为列表推导式(list),字典推导式(dict),集合推导式(set)三种 1.列表推导式也叫列表解析式.功能:是提供一种方便的列表创建方法,所以,列表解析式返回的是一个列表格式:用中括号括起 ...
- 转】C#接口-显式接口和隐式接口的实现
[转]C#接口-显式接口和隐式接口的实现 C#中对于接口的实现方式有隐式接口和显式接口两种: 类和接口都能调用到,事实上这就是“隐式接口实现”. 那么“显示接口实现”是神马模样呢? interface ...
- 流式布局&固定宽度&响应式&rem
我们现在在切页面布局的使用常用的单位是px,这是一个绝对单位,web app的屏幕适配有很多中做法,例如:流式布局.限死宽度,还有就是通过响应式来做,但是这些方案都不是最佳的解决方法. 1.流式布局: ...
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- 位置式PID与增量式PID算法
位置式PID与增量式PID算法 PID控制是一个二阶线性控制器 定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能. 优点 ...
- python的各种推导式(列表推导式、字典推导式、集合推导式)
推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...
- html响应式布局,css响应式布局,响应式布局入门
html响应式布局,css响应式布局,响应式布局入门 >>>>>>>>>>>>>>>>>>& ...
随机推荐
- RSA大会播报 – 2014最佳安全博客提名
今年美国RSA大会将在这个月的23-28号举行,每年大会上都会评出过去一年来业内最佳安全博客(Security Bloggers Network Social Security Awards 2014 ...
- JavaScript实现瀑布流
前端内容: 使用JavaScript和四个div,将照片放入四个div中 <!DOCTYPE html> <html lang="en"> <head ...
- Android -- 再来一发Intent
之前写过一篇Intent的博客,主要说了一下隐式意图. 传送门:<Android -- Intent> Intent对象构成 Component name.Action.Data.Cate ...
- MyEclipse发布按钮无效的办法
删除存放您MyEclipse项目的目录下的“/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.as ...
- iOS 图片比例缩放
方法 //Resize image - (UIImage *)resizeImage:(UIImage *)image withQuality:(CGInterpolationQuality)qual ...
- C/S 中当服务器进程崩溃的时候 SIGPIPE
程序还是https://github.com/juniperdiego/Unix-network-programming-of-mine/tree/master/tcpserv02 参考unix网络编 ...
- 数据库选型之MySQL(固态硬盘)
刘勇 Email: lyssym@sina.com 本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣! 简介 鉴于高频中心库 ...
- 从Intellij IDEA14 SpringMVC4+Hibernate4问题得到的启发
1.在添加model类hibernate注解的时候,idea一直提示没有配置数据源(其实是假报错,浪费我这么长时间,感觉idea还是和vs有很大的差距)! 2.解决上面的问题,又报错,原来id的注解写 ...
- Java注解总结
注解是Spring和Mybatis框架所大量使用的技术,要想掌握框架相关技术,注解是必须要掌握的. 掌握注解的优势: 1.能够读懂别人写的代码,特别是框架相关的代码. 2.本来可能需要很多配置文件,需 ...
- 复制web项目,启动的时候的工程名如何改变
右键项目->properties 然后 搜索 web 出现 Web Project Settings 右边看见 Context root 改成你希望的名字. 然后重启elipse