运用UML分析设计占先式实时内核
*中断。用来通知占先式实时内核有一个事件发生,包括内部非屏蔽中断、定时器中断与外部异步时间中断。
*系统时钟。用来创建中先式实时核所需要时候节拍。
(2)使用案例说明
*中断响应。占先式实时内核通过对异步事件的处理,获得任务运行所需要的信号与数据,使任务得以正常运行。
*中断级调度。中断处理使得需要该中断信号的任务就绪,调度程序判断该任务是否为当前任务就绪表中最高优先级任务,进而决定该任务否立即进行。
javascript:window.open(this.src);" style="cursor:pointer;"/>
*任务就绪。这里指的不是由于中断所引起的用户任务就绪,有两种方式:一个是,用户希望应用系统完成某个任务功能时,需要通知占先式实时内核,要求它创建该任务;另一个是,当当前运行的任务唤醒另一个任务时,使后者就绪。
*任务级调度。任务完成创建或被别的任务唤醒之后,调度程序判断该任务是否为当前任务就绪表中最高优先级任务,进而决定该任务是否立即进行。
*任务运行。当任务是当前任务就绪表中优先级最高的任务时运行该任务。
2.3 类图
图2为类图,包括一组由所讨论系统中抽象出的类和它们之间的关系。
类中断的属性中,中断类型包括非屏蔽中断、外部中断与定时器中断,以便占先式实时同核进行相应的中断处理;中断向量号与单片机的中断向量号相匹配;中断嵌套状态表明当前中断是处于哪一层的中断嵌套中。类中断有一个操作:中断处理,获取外部事件的信号和数据,并使上应的任务就绪,然后判断中断嵌套数是否为0。若不为零,执行别的中断响应;如果为零,选择相应的调度程序进行调度。
类调度的属性中,调度策略用于选择一种实时调度方案;调度类型包括中断调度与任务级调度;任务就绪表与任务悬挂表是调度时所需要数据结构。类调度有一个操作:调度。当当前任务是任务就绪表中优先级最高的任务时,当前任务继续运行;如不是,将当前任务运行时的状态与数据压入该任务堆栈,挂起该任务,然后调出最高级优先权任务的任务堆栈数据与状态,使最高级任务运行。
类任务的属性中,任务ID表明是哪一个任务;任务优先级说明任务在所有任务中的运行优先权;任务状态说明该任务在占先式实时内核中是处在何种状态;任务堆栈保存任务切换时该任务的状态与数据。类任务有四个操作:建立任务,在占先式实时内核中确认该任务;挂起任务,是任务由就绪状态转为挂起状态;恢复任务,是任务由挂起状态转为就绪状态;任务延迟,是任务自我延迟若干个时钟节拍,同时由就绪状态转为挂起状态。
类消息的属性中,消息类型包括信号量与消息队列;消息ID表明该消息是哪一个消息;消息发送任务ID表明消息是由哪个任务发送的;消息接收任务ID表明哪些任务接收该消息。类消息的操作有两个:发送消息,向一个或几个任务发送信息;接收消息,消息接收到某个信息。
类任务定时器的属性中,任务定时器ID表明该定时器是属于哪个任务的;任务定时器时长说明该任务需要多长时钟节后才能再次运行。类任务定时器中有两个操作:时钟节拍处理,处理任务的延时时钟节拍;任务超时处理,延时时间到的任务状态转为为就绪状态。
类之间有以下联系:
*中断与任务之间,描述中断处理使相应的任务就绪;
*中断与调度之间,描述由于中断引起的中断级调度;
*中断与消息之间,描述中断处理时,相应的消息得到信号或数据;
*调度与任务之间,描述由于调度使任务就绪表中优先级最高的任务运行,任务由于等待信号而自我挂起,也会请求调度;
*任务与任务定时器之间,描述定时器对任务延迟时间的处理;
*任务与消息之间,描述任务对消息的信息请求,消息对任务信息的接收,消息发送使接收该信息的任务就绪;
*调度与消息之间,描述由于消息到而请求调度。
2.4 状态图
状态图表示对象的行为,被用来描述一个系统的动态视图。由于在占先式实时内核中系统的状态转换可以通过任务的状态转换显示出来,所以这里只给出对象任务的状态务,如图3所示。
任务在占先式实时内核中具有就绪、运行、挂起三种状态。任务正在运行时,由于等待消息、自我延时或自我挂起,可以由运行状态进入挂起状态。当等待的消息到、等待超时或延迟到时,任务状态就由挂起状态进入就绪状态,任务如果是任务就绪表中优先级最高的任务,通过调度和任务切换,进入运行状态。
任务处于运行状态时,如中断发生,通过中断响应处理使任务就绪,并进行中断级调度:如果是任务就绪表中优先级最高的任务,继续运行;如不是,进行任务切换,任务由运行状态转变为就绪状态。
处于就绪状态时的任务,也可以由于当前运行任务的请求从就绪状态转变为挂起状态。
2.5 顺序图
占先式实时内核强调的是时间和事件。在UML中,顺序图是具有这种特性的动态交互模型。占先式实时内核的顺序力图4所示。
图4展示了中断和任务、任务和任务之间的交互情况,这也是占先式实时内核的基本内容。参与流程的对象在框图顶部的矩形中显示,共有五个对象:中断对象用来通知正在运行的任务有异步事件发生,并将正在运行任务的当前状态保存,暂停任务的运行;中断响应对象处理任务的中断服务代码,并将与中断信号相应的任务置为就绪状态,然后调度任务运行;低优先级任务和高优先级任务对象是用户希望系统所能实现的功能,低优先级任务只有当所有高优先级任务运行完毕或处于悬挂状态后才能运行;消息对象处理消息的发送与接收,消息接收表明有消息到来,然后消息发送使接收消息的任务状态转为就绪状态,进而进行任务级的调度,使高优先级的任务得以运行。
图4 占先式实时内核顺序图
3 占先式实时内核代码实现
在设计建模完成后,系统中对象的行为和它们之间的逻辑关系都已经清楚和确定下来,类和类的关系也得到进一步的抽象,这时需要选择具体的开发工具来实现占先式实时内核。在设计建模完成后,系统中对象的行为和它们之间的逻辑关系都已经清楚和确定下来,类和类的关系也得到进一步的抽象,这时需要选择具体的开发工具来实现占先式实时内核。我使用Cygnal IDE(集成开发环境)作为系统的软件开发平台。IDE支持C语言和汇编语言的源程序级调试,具有丰富的开发与测试工具。本系统采用C语言作为开发工具,具体设计不再详述。
结语
占先式实时内核在嵌入式系统开发应用中一直被认为是个难点,这主要是由于其内在关系比较复杂和繁琐,采用以往的方法往往会陷入反复设计和调试的过程中,最后实现的程序也会由于种种原因存在不易觉察的隐患,这样就会限制软件的推广和应用。
通过对占先式实时内核采用UML语言建模,可以比较清晰地认识到占先式实时内核在工作机制和具体实现过程各个阶段的工作内容,能够有效降低开发占先式实时内核所冒的风险,提高占先式实时内核编码和测试的效率与稳定性,缩短开发周期,这在嵌入式技术中有较好的实际意义。