基于RTSJ的嵌入式系统API的研究与应用
2011-06-22滕海坤陆二庆
滕海坤,陆二庆
(1.桂林理工大学信息科学与工程学院,桂林541004;2.黑河学院)
滕海坤(硕士研究生),研究方向为嵌入式系统;陆二庆(高级工程师),研究方向为嵌入式系统、计算机网络技术。
引 言
随着计算机技术、网络通信技术和微电子技术的迅猛发展和广泛应用,实时嵌入式系统(RTES)已经深入到科学研究和社会生活的各个领域。传统的观念认为,实时嵌入式系统一般采用过时或者晦涩的语言,如C/C++、汇编语言等。这些开发手段编程过于复杂、开发效率低、容易出错和安全性差等缺点已经成为嵌入式系统发展的阻碍。新一代的实时嵌入式系统期盼增加更多的新功能,这大大提高了嵌入式系统的复杂度,因此需要新的开发语言和手段促进实时嵌入式系统的开发应用。幸运的是,Java技术的特点弥补了上述缺点,并且越来越受嵌入式编程人员的青睐。Java实时规范[1-2]RTSJ(也称为Java规范申请JSR-001)的出现就是最好的例证。实时Java为实时程序员提供了一种为生产率而设计的现代主流语言。
Java实时规范(RTSJ)是实时Java专家组(RTJEG)制定的Java在实时性方面的扩展规范,弥补了Java语言在实时应用程序中的缺陷。它提供了创建、验证、分析、执行和管理实时Java线程的应用程序接口(API)。目前,国内外已经存在许多支持RTSJ的Java平台,并且已有相应成熟的商业产品。如TimeSys公司推出了第一个符合RTSJ的工业版嵌入式Java平台JTime[3],以及基于RTSJ扩展GCJ(GNU Compiler for Java)的jRate[4]运行时系统。jRate与其他实时Java平台有些不同,因为它将Java应用程序源代码提前编译(AOT)生成本地代码,这就意味着不需要Java虚拟机,节省了很多不必要的开销。然而,这些实现并不是针对实时嵌入式领域的,因为在嵌入式系统中开销足迹(footprint)要求与实时要求同样重要。本文的宗旨是利用可配置的嵌入式Java处理器FemtoJava[5]执行Java字节码,并且最优化地执行应用程序所需的有效操作码。定制的Java应用程序可以通过Sashimi开发环境编译,以VHDL形式实现处理器核心。Sashimi可以自动改装FemtoJava处理器的体系结构。FemtoJava是根据特定应用并基于FPGA技术设计的精简指令的哈佛结构处理器,它含有多个多路复用器和寄存器,以及一个唯一的ALU,较适合用于频繁变化的应用领域。
然而,Sashimi环境缺少一个表示并发的和实时约束条件的编程模型。本文的主要目标是通过提供基于RTSJ的支持并发任务规范的API弥补Sashimi环境的不足,这些API支持并发任务规范和时间限制规范。为了克服Sashimi环境这一限制,本文对 RTSJ规范进行了一些修改。在Sashimi环境上使用提供的API,程序员能够开发并发的实时应用程序,并且将它们部署到FemtoJava处理器,实现基于RTSJ的API在实际嵌入式系统中的应用。
1 Sashimi环境
Sashimi开发环境[5]是一个免费有效的嵌入式系统JVM 优化工具,开发人员可以用Java模拟、仿真和直接实现嵌入式系统。Sashimi环境可以通过扩展API支持并发任务,实现RTSJ标准。根据Sashimi环境的定义,设计人员可以直接使用Java语言开发他们的应用程序。为了满足Sashimi环境的约束条件,必须遵循一些编程限制。例如,程序员只可以使用Sashimi环境提供的API而不是标准的Java应用程序接口。此外,设计者们只可以使用静态方法和属性,因为目前Sashimi环境不支持对象的动态分配,也不支持类层次结构的继承和方法的多态性以及面向对象开发的基本概念。在Sashimi环境中,Java源代码使用标准Java编译器编译生成Java字节码。这些生成类可以在主机平台上使用仿真Sashimi环境的API类库进行测试。接下来的工作是,基于生成的Java字节码,综合应用程序和FemtoJava处理器生成一个定制的Femto-Java处理器控制单元。该控制单元仅支持应用程序使用的操作码。控制单元的大小与应用程序软件利用的不同操作码数量成正比,使其适合嵌入式系统应用。
另外,需要扩展Sashimi环境的API允许并发编程,增加一个动态任务调度的操作系统层,从而使Sashimi环境支持不同的调度算法。在开销足迹、能量消耗和实时性能方面,这些算法的影响评估在参考文献[6]中有详细描述。Sashimi环境的缺点是缺少高级的实时架构,导致设计师们只能使用低级系统调用生成并发进程,与调度器相互作用。此外,Sashimi环境没有任何机制清楚地表达任务时间限制。这些问题在下一小节通过提供的API进行处理。
2 基于RTSJ的APⅠ设计
正如前面所述,开发 API的主要目的是为基于FemtoJava微控制器的可配置的嵌入式系统的硬件/软件结构提供高级的实时编程架构支持。这些API是基于Java实时规范[1]制定的。它允许使用调度对象,该对象是实现Schedulable(调度)接口类的实例,和 RealtimeThread(实时线程)类一样。同时,它也提供了一组类的存储参数,这些参数表示一个或更多调度对象的特殊资源要求。例如,RaleaseParameters类(释放参数类,是AperiodicParameters和PeriodicParameters的父类)包含了一些满足实时需求规范的有用参数。此外,基于RTSJ的API还支持以下概念:时间值(绝对时间和相对时间)、定时器、周期性/零星、非周期性任务和调度策略。术语“任务”表示系统上下文的调度成员,也可以称为调度对象。以下是主要类的简单描述。
RealtimeThread:实时线程类扩展了默认的 java.lang.thread类。在实时嵌入式系统中RealtimeThread类表示一个实时任务,该任务是周期性的还是非周期性的,取决于给出的释放参数对象。如果任务使用PeriodicParameters类型的释放参数,那么任务是周期性的;如果任务使用的是AperiodicParameters或者SporadicParameters类的实例,那么任务是零星的、非周期性的。
ReleaseParameters:释放参数类是实时任务的所有释放参数的基类。ReleaseParameters类的实例包括发布的成本、启动时间、以及错过最后期限的处理器或者成本超支。它的子类PeriodicParameters和AperiodicParameters分别表示周期性和非周期性任务的释放参数。PeriodicParameters必须包含一个周期值和开始/结束的时间值。作为一个非周期性任务的类型,SporadicParameters类继承了AperiodicParameters类,偶发性任务的运行周期等于它的两次到达间隔的最小值。
SchedulingParameters:调度参数类是调度器对象使用的所有调度参数的基类。PriorityParamters类表示任务的优先级,它的实例分配给Schedulable对象,它们的执行资格是由优先级决定的。设计者们只需创建一个新的实例或共享现有的实例,提供一个整型值给构造函数作为优先级,并且分配给现有的Schedulable。
Scheduler:调度器本身是一个抽象类。它的子类“PriorityScheduler”、“RateM onotonicScheduler”和“EDFScheduler”分别表示固定优先、速率单调(Rate Monotonic)和最早期限优先调度算法。
HighResolutionTime:与 java.util.Date类相比,RTSJ对时间概念提供有力的支持。高解析度时间类是一个抽象类,不能实例化。不过它为所有其他高解析度时间类存储ms和 ns字段,并为它的子类 AbsoluteTime(绝对时间)、RelativeTime(相对时间)提供方法。绝对时间是以一个偏移量给出的,参考值是格林威治时间;相对时间总是一段持续的期限,它可以取整数、负数或零。另外,RationalTime(有理时间)类通过增加频率扩展了 RelativeTime类,它表达的是每段时间间隔内某事物发生的频率。
Clock:RTSJ支持多个时钟概念,基于RTSJ的Clock API定义了实时时钟表达全球性的时钟参考。该时钟类返回一个绝对时间对象表示系统的当前日期和时间。
Timer:定时器类是一个表示系统定时器的抽象类。它的子类OneShotTimer和PerodicTimer分别表示一次性定时器和周期性定时器。
本文一些API类的实现方式与RTSJ推荐的方式比较,有些微的差异,这是由于FemtoJava处理器结构的限制。在RealtimeThread类中就存在着这种差异。实时线程类中有两个抽象方法必须在它的子类中实现——mainTask()和exceptionTask()。它们分别表示任务主体(相当于普通Java线程的 run()方法)和错过最后期限的异常处理代码。后者代替了一个AsyncEventHandler(异步事件处理器)对象,在RTSJ中异步事件处理程序是设计用来处理实时应用程序可能需要处理的不同的系统和编程定义的事件,并且异步事件处理器对象应该传递给释放参数对象。如果任务错过了最后期限,则会抛出异常并且执行exceptionTask()函数。异常处理代码执行以后,任务执行流程可能会跳转到run()方法或者终止,这取决于实时任务的特征。如果任务是周期的,那么 run()方法应该重新启动。这种差异建议使用在任务对(taskpairs)概念的调度算法。
在第1小节中提到Sashimi环境的传统版本不支持对象创建。因此,为了给在FemtoJava平台上制定的API提供全面支持,需要扩展一些新属性到Sashimi环境。首先,需要扩展Sashimi环境支持对象的综合。根据相关修改,应用程序对象在合成时间进行静态分配。换言之,在系统中所有对象都定义了一个优先级,并且为了方便将对象存储到RAM中允许检测整个内存。虽然这种做法可能涉及到较高的内存用法,但是在实时系统开发中这种做法是非常适当的,因为它避免了垃圾收集器(GC)的使用。垃圾收集器算法没有时间限制,不可中断,使得Java运行程序相当缺乏确定性。在实时嵌入式系统中这种不确定性是不能容忍的。
FemtoJava微处理器引入了4个新的操作码以支持提供的 API:getfiel、putfield、invokevirtual和 invokespecial。前面两个操作码与对象区域的访问相关,它们的功能分别是获取和设定值。另外两个操作码与方法调用相关,invokevirtual操作码用来调用公共的或者受保护的方法,invokespecial操作码用来调用构造函数和私有方法。FemtoJava微处理器的另一个扩展是增加一个实时时钟,用来提供嵌入式系统的时间概念。基于RTSJ的API成员和调度层都可以使用这个时钟。
3 APⅠ在实际嵌入式系统中的应用
本文选用电梯控制系统[7]作为验证Sashimi环境扩展的案例。该系统是一种多台电梯优化调度的系统,包含了并发任务和硬实时限制条件。由于电梯控制系统任务的多样性,传统的开发手段将很难解决在线调度及资源配置的组合优化问题。本文使用实时Java多线程技术改变了这些现状。图1表示电梯控制系统的类协作图,从图中可以观察出,Timer类实现了Sashimi环境的任务时间限制条件。其通过getRealtimeClock()方法调用实时时钟对象,获得单一实时时钟的引用。
图1 电梯控制系统的类协作图
虽然电梯控制系统中包含了很多类,但是本文将主要讨论LiftInitializer和LiftDoor类,因为笔者认为这两个类在API的使用中具有足够的代表性。LiftInitializer类是电梯控制系统实现的主要类。这个类的功能是负责对象分配、初始化和启动(实时任务应用)。从电梯控制系统代码中能够看到,只有静态对象被分配。initSystem()方法表示应用程序执行流程的起始点,并且提供对象初始化和实时任务启动的功能。实时任务启动可以通过调用start()方法实现。代码的最后调用了 sleep()方法,这就意味着这个初始化类不再使用并被锁定。这种做法仅在系统初始化方法中使用。电梯控制系统的LiftInitializer类代码如下:
LiftDoor类在系统中关联模式表示一个并发实时任务,与系统时钟有着密切的关系。本文使用一个自定义异步事件和一个一次性定时器分别实现电梯门打开和关闭的任务。在电梯门应用中,FloorSensor类是一个事件处理程序,等待听到请求的楼层已经到达。当它到达时,它停止电梯并打开门。这个举动触发了关闭定时器(One-ShotTimer类),其处理类是DoorTimer。当它触发时,在等待10 s后,closeDoors方法被调用,电梯按设定将开始再次移动。作为一次性定时器,门定时器不会再次触发,除非用户再次调用它的enable和start方法。电梯门类部分代码:
本文最后的工作是整合API、Sashimi环境和Femto-Java处理器生成完整的嵌入式系统。Sashimi环境把Java编译器生成的 Java类文件作为输入,生成FemtoJava处理器的硬件单元(以VHDL文件形式)和嵌入式系统的应用软件。由优化的Sashimi环境生成的FemtoJava处理器是非常重要的,因为它只支持嵌入式系统软件使用的Java操作码。另一个值得注意的是:一旦应用程序对象在整合时间内分配,就没有必要使用垃圾收集器。虽然这会导致较高的内存消耗,但是它提供了实时嵌入式系统的确定性要求。
结 语
本文的目标是使用基于RTSJ的API,优化实时嵌入式系统开发。该API是以专门执行Java字节码的FemtoJava处理器为目标平台。这些API为程序员提供了必要的工具来解决虚拟机和应用程序中的易变性,并且程序员可以在实时应用程序中使用高级机制表示并发和时间性的约束条件。为了保证API尽可能地接近RTSJ规范,对RTSJ规范进行了较小的修改,进一步提高了嵌入式实时性的服务质量。同时,实时Java所具备的优势将极大地改变嵌入式控制软件的设计难度。相信在未来的几年里,实时Java技术将会给嵌入式控制领域带来巨大的影响。
[1]Greg Bollella,James Gosling.The Real-Time Specification for Java[OL].[2011-04].http://www.rtj.org/rtsj-V1.0.pdf.
[2]Bruno Eric J,Bollella Greg.Java实时编程[M].田思源,译.北京:机械工业出版社,2010.
[4]Corsaro Angelo,Schmidt Douglas C.The Design and Performance of the jRate Real-time Java Implementation[C]//the 4th International Symposium on Distributed Objects and Applications.Irvine,CA,October-November,2002.
[5]S A Ito,L Carro,R P Jacobi.M aking Java Work for Microcontroller Applications[J].IEEE Design&Test of Computers,2001,18(5).
[6]L B Becker,M A Wehrmeister,L Carro,et al.Evaluating High-level Models for Real-Time Embedded Systems Design[C]//29thWorkshop on Real-Time Programming.Istanbul,2004.
[7]曹建忠,罗飞,等.新型电梯群控系统的建模和控制策略研究[J].微计算机信息,2006,22(13).