freertos中任务的调度方式

一、freertos的调度方式

在单核心处理器在任何给定时间只能有一个任务处于运行状态。

FreeRTOS操作系统支持三种调度方式:抢占式调度(Pre-emptive),时间片调度(time slice)和合作式调度(co-operative)。实际应用主要是抢占式调度和时间片调度结合的调度方法,合作式调度用到的很少。

co-operative = Non-Pre-emptive = 不可剥夺 = 非抢占式

Pre-emptive = 抢占式 = 可剥夺

1、抢占式调度(Pre-emptive)

Pre-emptive scheduling algorithms will immediately ‘pre-empt’ the Running state task if a task that has a priority higher than the Running state task enters the Ready state. Being pre-empted means bein involuntarily (without explicitly yielding or blocking) moved out of the Running state and into the Ready state to allow a different task to enter the Running state.

CPU总是运行多个任务中优先级别最高的那个任务,即使CPU正在运行某个低级别的任务,当有更高优先级别的任务准备就绪时,更高优先级别的任务就会剥夺正在运行任务的CPU使用权,从而使自己获得CPU的使用权。

上图中任务优先级:

Task1 > Task2 > Task3 > idle Task

空闲任务以最低优先级运行,因此每次更高优先级的任务进入就绪状态时都会被抢占——例如,在时间 t3、t5 和 t9。

task 3 是一个事件驱动的任务,以相对较低的优先级执行,但高于空闲优先级。

task 2是是一个周期性任务,分别在t1、t6和t9执行。

2、合作式调度(co-operative)

When the co-operative scheduler is used, a context switch will only occur when the Running state task enters the Blocked state, or the Running state task explicitly yields (manually requests a re-schedule) by calling taskYIELD(). Tasks are never pre-empted, so time slicing cannot be used.

使用合作调度器时,只有在Running状态任务进入Blocked状态,或者Running状态任务通过调用taskYIELD()显式让步(手动请求重新调度)时才会发生任务切换。 任务永远不会被抢占,因此不能使用时间切片。

虚线表示任务处于就绪状态

task 1 具有最高优先级。 它以阻塞状态开始,等待信号量。在时间 t3 一个中断给出信号量,导致任务 1 离开阻塞状态并进入就绪状态。但是在co-operative调度模式下task1并不会立即执行,因为task3还在占用调度器。

task 2:在时间 t2 task2 是最高优先级的就绪状态任务,但由于是co-operative调度模式,task2并不会立即执行,除非task3进入阻塞状态或者调用taskYIELD()。在T4,task3调用taskYIELD()让出调度器,但此时task 1 是最高优先级的就绪状态任务,所以任务 2 并没有真正执行,直到任task1 在 t5 重新进入阻塞状态。

3、时间片调度(time slice)

在FreeRTOS操作系统中只有同优先级任务才会使用时间片调度。最常用的的时间片调度算法就是Round-robin调度算法(时间片轮转),freertos就是用的该算法。一个时间片等于freertos中滴答定时器的时间间隔。

上图中任务优先级:

Task1 = Task2 = Task3 = Task4

先运行Task1,运行够一个时间片后,通过时间片调度切换到Task2。Task2 运行够一个时间片后,通过时间片调度切换到Task3。

Task3 在运行期间调用了阻塞式 API 函数,虽然一个时间片还没有用完,此时依然会通过时间片调度切换到下一个任务 Task4。 (注意,没有用完的时间片不会再使用,下次任务 Task3 得到执行还是按照 一个时间片运行),任务 Task4 运行够一个时间片后,通过时间片调度切换到任务 Task1。

二、抢占式调度和时间片调度结合的调度方法

这种方法是freertos中常用的调度方法,示意图如下:

上图中的优先级:

task 1 > task 2 = idle task

上图中一个新的时间片开始在每一个滴答定时器中断上,t1、t2、t3、t4、t5、t8、t9、t10 和 t11。

在t1 - t5,只有task2和idle task两个任务,这两个task 优先级相等(都是0),因此调度器将轮流执行这两个任务。即t1 - t2分配给idle task,t2 - t3分配给task2,t3 - t4分配给idle task .......(t1 -t2时间间隔也就是time slicing,一般是systick中断时间)。

在t5 -t8时间段,前段在执行idle task,中段task1打断了idle task,task 1执行完毕之后,由于要轮流执行,所以后段执行的是task2。到了t8,到了下一个slice time,切换到idle task继续执行。

在上图中,task2和idle task的优先级相同(都是0)。则在没有其他更高优先级的任务的时候,这两个任务轮流调度。但如果task2有工作要做,但idle task是空任务,那么将那么多处理时间分配给idle task可能是不可取的。因此,freertos中可以通过设置configIDLE_SHOULD_YIELD来减小idle task的占用时间。

  • 如果 configIDLE_SHOULD_YIELD 设置为 0,则空闲任务将在其整个时间片内保持运行状态,除非它被更高优先级的任务抢占。(就是上面图片的所示)
  • 如果 configIDLE_SHOULD_YIELD 设置为 1,那么如果有其他空闲优先级任务处于就绪状态,则空闲任务将在其循环的每次迭代中让步(自愿放弃其分配的时间片的剩余部分)。如下图所示:

ref:

https://www.freertos.org/Documentation/RTOS_book.html

https://blog.csdn.net/baidu_15547923/article/details/100043209

https://www.cnblogs.com/sky-heaven/p/13475976.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值