引言
嵌入式系统的发展非常迅速,已经极大地改变了人们的生活、工作和娱乐方式。随着硬件的急速发展,现在的嵌入式系统大多集成度很高,CPU的信息吞吐量极大提高,系统功能复杂。对于这些变化,嵌入式系统中往往采用实时操作系统(RTOS)来简化开发过程,增强可读性。实时操作系统能很好地把工程师从枯躁的系统监控程序和繁琐的系统资源管理中摆脱出来,专心投入于产品功能的设计和测试当中。但操作系统模式下软件结构的安排与以前的前后台系统不一样。在操作系统模式下,一般都是将要设计的软件系统分为一系列独立的事件来处理,即任务。系统内核管理着这些任务,并且保证对系统时间要求严格的事件能够得到有效的执行。因此,如何把即将设计的软件系统有效地划分成不同的任务,将直接影响到产品的稳定性和可维护性。如果划分不合理,会给调试带来很大麻烦。
1任务划分
1.1总体框架安排
将产品的软件系统划分为多任务系统时,首先要分析用户需求、定义软件系统的各功能模块,并进行各功能模块间数据流的分析,画出相应的数据流图;然后对软件系统内所实现的功能进行划分,构造成多任务系统中运行的任务。一般来说,按照软件系统的状态图将软件系统分成以下2种结构。
1.1.1单链多任务系统
虽然整个软件系统由多个任务组成, 但单链多任务系统的主要输入只有一个。因此,可以想办法把这些任务提取出来,构成链式多任务系统来完成要设计的软件系统。当要设计的产品功能比较单一、明确时,经过划分很可能就成为单输入、单链式执行的单条任务链系统,如图1所示。
图1单链多任务系统
当然,这并不代表所设计的单链多任务系统中没有其他分支,之所以未在图中画出来,只是为了突出单链式结构的特点。
1.1.2多链多任务系统
如果一个软件系统划分成多任务系统后,根据数据流图(或者状态转换流图)可知,要处理各种不同的事件,且每一个事件都有对应的任务链, 则经过这样划分的多任务系统就是一个多链多任务系统。其典型结构如图2所示。
图2多链多任务系统
1.2单链多任务系统中任务划分的基本原则
多链式雷同于单链式的,只是每个不同的状态或者输入引导到不同的任务链。在单链多任务系统中,由于所划分任务的好坏直接影响到了系统性能的好坏和执行效率的高低。因此,在进行系统设计时,任务的划分应当成为设计的重点。任务划分存在这样一对矛盾:如果任务太多,必然增加系统任务切换的开销;如果任务太少,就会降低系统的并行度,实时性就比较差。在任务划分时要遵循H.Gomma原则:
① I/O原则:对于不同的外设,应该划分为不同的任务。
② 优先级原则:对于突发性事件,应划分为不同优先级的不同任务。
③ 大量运算:也称为“数据处理任务”。用户应用程序中消耗机时最多的是各种数据处理程序单元。这些单元分别为不同的功能服务,应该将这些任务划分出来归为一个任务;另外由于这类任务消耗较多的机时,所以它们的优先级必须安排得低一些。
④ 功能耦合:将关系密切的若干功能组合起来,归为一个任务。
⑤ 偶然耦合:归为一个任务。
⑥ 频率组合:对于经常重复发生的事件,发生频率不同的事件划分为不同任务。
进行系统任务划分除了遵循H.Gomma原则以外,还有就是考虑系统中所实现功能间的异步关系。如果在具体分析一个系统时发生原则冲突,则要为每一个原则针对具体的系统设定“权重”,必要时可以通过计算“权重”来最终确定如何划分任务。
1.3任务划分后的结果
经过上面的划分,一般可把划分的任务归为3大类:
(1) 控制任务
控制任务是执行状态机或控制功能的代码集,经常用于实现状态转移表。具有简单状态转移的系统,可使用非周期策略,即状态机中的每一个状态都可用独立的异步任务实现;但对于具有复杂状态转移的系统就不适用了,因为在状态间传递的数据量太大。这时,控制任务应当被写成可重入代码,且在系统运行时为状态机的每一个实例创建该控制任务的一个拷贝。采用这种策略对设计者提出了新的要求——确保这些任务对共享数据的互斥操作。
(2) 周期任务
周期任务多指在一个固定周期内必须完成一次的任务。由于周期性要求,往往在任务安排时,它的工作时间短,任务优先级别高。
(3) 异步任务
异步任务(非周期性任务)是指根据命令执行和用于处理内部事件的任务。异步任务用于实现异步功能,在许多系统中大多数任务都是异步的。
2不同调度算法下的任务优先级分配
经过前面的工作,基本划分出了所需要的任务。在完成多任务系统划分后,下一步就是优先级的分配了。这里主要讨论的是抢占式调度,至于片轮式调度模式,由于其缺点越来越明显,在操作系统中用得越来越少,就不作讨论了。那么优先级的安排有哪些基本方法或原则呢?我们来看一下目前最常用的几种任务调度式算法,以及在这种算法下优先级的安排方法。
2.1速率单调调度算法RMS下的优先级安排
2.1.1速率单调调度算法RMS
任务的优先级按照速率单调优先级分配(RMPA)的算法形成的调度称为“速率单调调度(RateMonotonic Scheduling,RMS)”。在基于静态调度的情况下,RMS是常用的最优的优先级调度方法之一。
RMS的基本公式(含测试公式)是:
式中: n为任务总个数;Ci为任务i执行一次的最长时间,Ti为任务i的周期,Ci/Ti为任务i的CPU占用率;U(n)为采用该调度算法时CPU占用率的上限。
RMS是基于周期任务的,如果系统含有非周期性任务,则按2.1.2小节中的方法进行调整。
2.1.2基于RMS的非周期任务的调度
实时系统中的非周期任务可采用“延迟服务器算法”或“随机服务器算法”进行调度。它们的最大特点是可在周期任务的实时调度环境下处理随机请求。两者的基本思想是将非周期任务转化成周期任务,再利用RMS算法进行调度。前者用一个或几个专用的周期任务执行所有非周期任务,这种周期任务叫非周期任务服务器。根据周期大小,服务器有固定优先级,服务器的执行时间称为“预算”,它在每个服务器周期Ts的起点补充。只要服务器有充足的预算,就可在其周期内为非周期任务服务。该算法实现简单,但可调度性分析较难,有时会出现抖动,可能发生一个非周期任务在相邻两个服务器周期中连续执行2倍预算的现象,与RMS理论不符,需要适当修改RMS算法。随机服务器算法与延迟服务器算法相似,但预算不是在每个周期起点补充,而是在预算消耗Ts时间之后再补充。该算法与RMS分析算法一致,但实现复杂。
2.1.3RMS算法下的优先级安排
如果完全按照RMS算法的要求来安排任务,那么得到的结果将是根据任务的周期来设置任务的优先级别,周期越短,其优先级越高。在实际使用中,还要按照划分任务的结果及任务的一些属性进行调整。划分时应考虑到如下因素并对其进行调整:
① 中断的前期处理相关任务要将其优先级调高。由于中断是用来处理异步事件的,在中断里不可能放更多的相关数据处理程序,导致中断所产生的相关数据积压下来,所以要将中断数据的前期处理任务的优先级调高一些。
② 有些异步任务对响应时间有要求,如读网卡或串口的数据,以及固定时间内要刷新某些控制单元或数据。
③ 数据处理任务及前面提到的控制任务,优先级可以安排得低一些。尤其是数据处理任务,当对最终数据要求不是很高时,可以让CPU在比较空闲时集中处理。
2.1.4评判基于RMS的任务是否可正常执行
由RMS的基本公式可知,随着任务数目的增加,操作系统的负荷也加重,可供任务利用的CPU机时减少,即U(n)随着任务数目的增加而下降,如表1所列。
表1任务总数与利用系数的关系
判别方法: 根据表1可知,当系统只有1个任务时,其CPU的占用率(Ci/Ti)≤1;当有2个任务时,其CPU的占用率之和∑1≤i≤2(Ci/Ti)≤0.828;当有3个任务时,以此类推。
只要满足RMS的测试公式,系统就可以正常运行;否则,系统的正常运行难以保证。
2.2最早死线优先算法EDF下的优先级安排
最早死线优先算法(Earliest Deadline First,EDF)也称为“死线驱动调度算法”,是一种动态调度算法。动态是指任务的优先级在执行时可根据需要进行变动。
2.2.1最早死线优先算法EDF
EDF算法的核心思想是指在调度时刻,任务的优先级根据任务的死线(deadline)动态分配。死线越短,优先级越高。也就是说,采用EDF,必须根据任务的死线要求在系统工作过程中动态调整任务的优先级别,提高任务接近死线的紧迫任务的优先级,使尽可能多的死线要求得到满足。应用EDF调度算法时,系统的CPU利用率可达到100%。
EDF算法有如下定理:如果一个任务集合按照EDF算法可调度,则当且仅当U≤1。
2.2.2EDF调度算法的缺点
系统采用EDF调度算法时,每次选择下一个要执行的任务,都要分析整个任务链表,从中选择时限最早的就绪任务。分析整个任务链表会消耗大量的系统时间及系统资源,而且调度开销会随着任务数和上下文切换次数的增加而剧增,甚至导致实时系统崩溃。
2.2.3EDF算法下的优先级安排
EDF算法下的优先级是由系统自动调整的,唯一要确定的是任务的死线。当发生任务调度时,系统会调用schedule搜索,找出sched_priority值中最大的那些任务;然后调用cmp_prio中current_deadline 最低的那一个,即为优先级最高的任务。
3应用举例
我们基于Philips公司的LPC2210和μC/OSII操作系统,设计了一个用Internet网络进行通话的电话机。完整的网络电话机的工作图如图3所示。
图3完整的网络电话机工作图
电话机工作情况如下:
① 所有电话机在通电时,都先主动向服务器登记自己的一些参数(包括IP地址、电话号码、硬件版本、软件版本等)。
② 当电话机A想拨打电话机B时(电话号码必须已知),首先向服务器(号码与IP解析专用服务器)发送一个数据包,用来查询当前电话机B所在的IP地址和状态。此时服务器会向电话机B发出握手联络,以确认电话机B目前正常并处于待机状态。在确认电话机B正常后,把电话机B目前的状态(含IP地址、目前状态)发给电话机A。
③ 电话机A从服务器获取电话机B的状态包后,确认电话机B目前不处于繁忙中,向目前的Internet网络查找电话机B,并与之通信。
按照所介绍的任务链的划分原则,可以得到图4所示的任务链。
图4划分后的多链多任务实例
图4已经包含了已经划分好的任务(8个)、任务链(3个)、任务链的优先级(3个)。那么现在按照速率单调调度算法RMS来安排优先级,结果如图5所示。
图5每条任务链下的任务优先级安排
最终的产品结构清晰,稳定性好,可维护性高。可见,按照上述原则可以帮我们安排好软件构架,包括任务链的划分、任务的划分、任务的优先级安排等,有利于开发出更好的软件。
结语
本文主要讨论了在实时操作系统下设计软件时最需要注意的3个问题:任务链的划分;任务划分的几个基本原则和划分后得到的几种结果;不同调度算法下的任务优先级的分配。需要说明的是,本文所列的原则并不能包括任务划分和优先级分配的各个方面,许多方面还需要在实际开发实时系统时不断地总结。另外,在使用以上的原则时,应当根据系统的具体特点灵活考虑,不能死搬硬套,抱着某一条原则不放。比如在优先级安排时,就必须考虑到任务的关键性、紧迫性、设备依赖性等加权因素的影响。
总之,一个即将要设计的软件系统,能不能划分成一个好的多任务系统,能不能更合理地分配优先级,直接影响到产品的稳定性和可维护性。在实际操作时既要参考这些原则,又要根据实际任务的情况进行调整,必要时还需要在硬件上运行起来进行比较。