APP下载

一种基于FreeRTOS实时系统改进的时间片延迟调度算法的设计

2019-11-05汪千松

科技视界 2019年28期

汪千松

【摘 要】通过对FreeRTOS同优先级任务的最后几次执行时间片进行优化,提出了改进的时间片延迟调度算法,使任务在最后几次执行时不进行时间片切换而继续运行。改进的调度算法在保证实时性的同时也大大提高了任务的执行效率,增大了系统吞吐率。

【关键词】FreeRTOS;同优先级;时间片

中图分类号: TP23 文献标识码: A 文章编号: 2095-2457(2019)28-0043-002

DOI:10.19694/j.cnki.issn2095-2457.2019.28.015

0 引言

FreeRTOS可采用抢占式和时间片轮转混合的调度机制[1],其原先的基于时间片轮转调度存在某些不足,当同优先级任务快速增多时,任务的频繁切换会加大系统的业务和能量开销,使任务具体结束时间延长。改进的时间片延迟调度算法通过直接让任务在最后几次执行时不进行时间片切换而继续运行结束,提前时间点让出CPU给其他任务运行,减少任务频繁切换的次数。当高优先级任务到来时仍然能及时响应执行,在保证实时性的同时也提高了整体任务的执行效率,增大了系统吞吐率。

1 算法原理

1.1 FreeRTOS默认时间片调度算法

FreeRTOS操作系统此前的同优先级的任务时间片轮转调度算法将任务的处理时间划分为一个固定的时间片大小,时间片用完将进行切换,而且时间片的值则固定设置为一个系统时钟节拍。同优先级的任务就绪列表中各个任务按排列的顺序轮流占用固定时间的CPU资源[2]。当某个任务的时间片用完时,而本身的任务没有结束时,其必须让出CPU的使用权,使自身进入同优先级就绪列表的尾部中,等待下次轮转的再次调度。同时调度器运用调度算法又会去选择同优先级就绪列表中处于头部的就绪任务,分配一个时间片,让其占用CPU资源而运行。也就是说一个任务到了时间点即使没有运行完成也必须让出CPU的使用权切换出去,给就绪的其他任务继续运行的机会。

1.2 改进的时间片延迟调度算法

改进后的算法其原理为在时间片轮转调度的情况下,对任务的最后几次执行时间片(数值可调整)进行优化。也就是当任务是按照时间片轮转调度算法进行时,当任务的最后几次运行时间少于时间片数值的1.5倍(数值可调整)时,该时间片调度算法不发生任务的切换操作,使任务继续占用CPU的资源,从而使任务提前结束完成,让其他的任务有更多执行的机会。

2 算法设计实现

2.1 任务运行时间设计

FreeRTOS中在任务创建的过程中并没有指定任务运行的时间大小,只是根据自己需要而进行任务的停止删除,其主要原因是任务的数据结构中并没有记录任务执行时间的变量。基于此不足,我们必须在任务的数据结构中添加相应的变量来记录任务执行时间,现有如下的改进方案。

在任务控制块里添加相应的时间相关变量。我们知道任务控制块是记录着一个任务一些属性,将任务执行时间相关的变量加入到任务控制块中可使代码看起来更直观,增强可读性。至此,我们在任务控制块中添加了三个与任务时间相关变量。分别为剩余执行时间变量ulRemainTimeSlice、初始化执行时间ulReloadTimeSlice、任务不切换连续执行时间片ulThresholdTimeSlice。当ulThresholdTimeSlice值为0时代表该改进算法无效,与之前的调度算法功能相同。在添加变量的同时再添加相对应的函数来设置和获取对应变量的值。在任务执行过程时,还添加了任务剩余时间递减函数,具体执行的操作为使任务执行时间片递减。

2.2 任务切换设计

在任务的调度过程中FreeRTOS的任务切换的触发场合有执行一个系统调用和系统滴答定时器中断两种方式。而在时间片轮转调度的正常情况下一般是发生系统滴答定时器中断而发生任务切换。之前的时间片轮转调度是只要时间到了就会发生任务的切换操作,基于该切换的不足,我们改进的算法必须使调度器满足必要的条件后不发生切换继而继续运行。现有的改进方案如下。

在滴答定时器中断服务函数SysTic_Handler()中,其会调用FreeRTOS的API函数xPortSysTickHandler(),其在文件port.c中,在xPortSysTickHandler()函數中会发生任务的切换调度操作。而这个任务切换调度操作是有条件的,其需要满足xTaskIncrementTick()!= pdFAlSE,而函数xTaskIncrementTick()一般用于检测当前任务所对应的任务优先级下是否还有其他任务,有的话就返回pdTRUE。基于此,我们在创建同优先级任务的时候一般要多于2个,这样方便测试对比。在该条件成立的情况下,我们就可以在内部进行适当的处理,使任务满足指定的条件需求后才进行任务的切换操作。修改后的void xPortSysTickHandler()函数部分代码如下所示:

xTaskDecreaseRemainTimeSlice();

if( 0 != xTaskGetThresholdTimeSlice() ) {

if(xTaskGetRemainTimeSlice()>xTaskGetThreshold TimeS lice() ) {

/* A context switch is required.Context switching is performed in

the PendSV interrupt.Pend the PendSV interru pt.*/

portNVIC_INT_CTRL_REG=portNVIC_PENDSVSE T_ BIT;

} else if ( 0 == xTaskGetRemainTimeSlice() ){

/* ... */

}

} else {

portNVIC_INT_CTRL_REG=portNVIC_PENDSVSE T_BIT;

}

由上可以看出,当函数xTaskIncrementTick()成立时,我们首先调用xTaskDecreaseRemainTimeSlice()函数对当前任务的时间片大小进行递减操作,同时接下来调用xTaskGetThresholdTimeSlice()函数来判断设置的需要延迟的时间片大小,如果为零的话,将和往常一样进行任务的切换操作。而如果不为零的话,则继续进行相对应的处理,其首先是判断剩余的执行时间片大小是否大于设置的需要延迟的时间片的大小,如果大于的话,说明任务不需要继续延迟,进而发生切换操作。而如果不大于的话,说明到了需要进行延迟的时间点,任务不发生切换,继续占用CPU资源执行代码。当任务的剩余时间片大小等于零的时候,说明任务需要执行的时间片已经全部用完,继而可以删除任务将其停止,让出CPU资源给其他任务运行。

3 算法性能分析

下面对FreeRTOS改进的时间片延迟调度算法做基本的性能分析。假设有三个同优先级的任务T1,T2,T3。其所需的执行时间分别为100,50,60,单位为一个时间片大小。其中为了显示的效果明显,将时间片周期设置为了50ms。则改进的时间片延迟调度算法在以下各种情况中行结果如表1所示。

表中A为改进后当任务都延迟3个时间片运行得到的结果;B为改进后当T1,T2,T3分别延迟1,2,3个时间片时运行得到的结果;C为改进后当T1,T2,T3分别延迟3,2,1个时间片时运行得到的结果。

由表中的数据结果分析可得当任务最后几次执行时间(数值可根据实际情况调整)不发生任务切换而继续运行时,任务能比原先提前时间完成。即改进后时间片轮转调度优化算法能够减少任务的调度次数,缩短CPU周转时间,故而可以降低任务实际完成时间,同时减少了系统业务开销和能量开销,提升系统运行效率,使系统的性能得到了一定的提高。

4 结论

改进的时间片轮转调度算法在任务最后几次执行时可以减少切换次数,缩短CPU周转时间,提高系统效率,不管是用在通用操作系统还是在实时操作系统上,都具有实际的应用价值[4],但其仍存在不足,当任务的个数较少且延时时间片比较长时,势必会影响其他任务的运行,虽然执行的任务可以提前结束,但其他同优先级任务某些时候可能也需要适当的实时性要求,这样由于任务得不到适当的响应而使系统表现得整体性能看起來而有所降低。所以进一步动态分析选取任务的延时时间片大小是一个值得深入研究的问题,当任务的延迟时间选取合适时,将对系统的效率带来大大的提升。

【参考文献】

[1]Guan F,Peng L,Perneel L,et al.Open source FreeRTOS as a case study in real-time operating system evolution[J].Journal of Systems and Software,2016.

[2]朱迪.FreeRTOS实时操作系统任务调度优化的研究与实现[D].南京邮电大学,2015.

[3]左中凯.FreeRTOS源码详解与应用开发---基于STM32.北京:北京航空航天大学出版社,2017.

[4]肖建明,张向利.一种改进的时间片轮转调度算法[J].计算机应用,2005.