2. 武汉大学 软件工程国家重点实验室, 武汉 430072
2. State Key Laboratory of Software Engineering, Wuhan University, Wuhan 430072, China
随着现代信息化技术的高速发展,嵌入式系统的核心往往由一个或多个编制好软件的微控制器组成.嵌入式系统开发与传统软件开发具有很大的不同:与通用计算机软件相比,嵌入式软件的规模较小、数据结构简单,但是控制逻辑复杂、硬件接口种类繁多,而且嵌入式软件常常运行在安全关键性的场合.目前嵌入式软件多数是运行在嵌入式操作系统之上的,而当前的嵌入式操作系统非常多,如Linux、uCLinux、VxWorks等.开发人员往往需要针对不同的开发平台,分别设计相同的应用.在实际的嵌入式软件开发过程中,由于微控制器需要与多种类型的数字/模拟信号接口的物理设备交互,专业的软件设计人员缺乏对这些物理设备的专业知识,无法担任程序的测试、仿真、调试等任务,所以通常由专业的电子工程师承担大部分的软件设计、调试任务.但是电子工程师缺乏计算机专业知识,对所使用软件设计中的系统类型、程序语义、内存模型等问题无法完全掌握,因此造成软件开发效率不高、软件质量无法控制、软件可靠性低、容错性差、软件重用性低等问题.
软件综合(software synthesis)方法通过提高代码生成的自动化程度来避免在嵌入式系统开发中遇到的上述问题.软件综合是一种将抽象的软件模型自动转换或翻译为具体的程序设计语言实现的方法.已有的相关工作大致分为以下两类.
在通用软件建模与代码生成方面,主要以面向对象方法为主,围绕UML展开建模语言及其翻译方法研究.其中最成熟的是对UML Statecharts的转换方法研究:Wagner和Samek等[1, 2]研究如何用C/C++表示UML Statecharts模型;Wasowski[3]研究如何将Statecharts模型综合为高效的代码,其主要贡献是通过状态编码的方法削减Statecharts平面化后的状态数.Krüger等[4, 5]研究在面向服务的体系结构中将MSC(顺序图的一种形式化变体)转换为一种面向方面的Java程序——AspectJ.Maoz等[6, 7]在MSC的基础上,提出了用LSC为对象间的行为建模,并研究如何将LSC模型编译为AspectJ.基于UML顺序图的转换方法的限制在于顺序图描述的是对象实例之间的行为,只能描述系统某些时刻的行为而不能作为系统的整体设计,所以该方法只能产生系统中的程序片段.
在实时系统方面的代码综合方面,主要以同步语义为核心,研究建模语言、综合方法与工具.其中最具代表意义的建模方法和语言包括Lustre[8]、Esterel[9]、SyncCharts[10]、Simulink[11]等.在程序转换,文献[12, 13]将Esterel综合为基于自动机的C语言程序.而Halbwachs等[14]研究从数据流语言到C语言的编译与控制流优化方法.最新的研究主要是面向不同的硬件平台实施的优化算法[15, 16].这类方法的共同点是使用同步语言对系统建模,然后生成C语言或RTL语言程序,结合手工编制的宿主(Host)程序,综合为最终的软件/硬件系统.就国内而言,对综合方法的研究主要集中在电子辅助设计相关的领域,包括国防科学技术大学[17]、北京理工大学[18]在EDA工具、VHDL的综合方法上展开了深入的研究.而与软件综合相关的研究主要集中在模型转换与基于构件的软件开发方法上,其中,北京大学[19, 20]提出了一种动态、可定制的构件自主化的实现手段及运行平台;华东师范大学[21]提出了一种基于统一程序设计理论的模型构造与集成策略;国防科学技术大学[22]研究了支持软件环境适应能力细粒度在线调整的构件模型;南开大学[23]研究了网构软件可信智能实体模型以是实现网构软件的保障与管理;中国科学院[24]研究了基于共享位置的Petri网模型合成方法;南京大学[25]研究了基于场景规约的构件式系统设计分析与验证技术;而哈尔滨工业大学[26]则针对构件匹配提出了一种基于有限自动机的多层次的构件行为匹配模型.
综上所述,已有的软件综合方法研究存在的主要问题有:①现有的研究一般将模型转换为某一种宿主语言(C/C++/Java),不能适应多平台目标系统的需要,而且目标代码的可读性比较差,效率较低.②现有的方法只能生成部分代码,需要将生成的代码嵌入到手工编制的代码中才能构成完整的程序.而在手工编制的代码中的副作用会影响到生成代码的性质,使得最终程序的性质与初始的模型性质不一致.
针对这些问题,本文提出了利用与实现无关的描述方法,提出一种基于Esterel代码自动生成的方法.将嵌入式系统模型直接转换为与具体平台相关的可执行程序,从而实现在微控制器软件设计这个特定领域的程序设计自动化.
1 多目标平台的代码自动生成
1.1 Esterel语言
Esterel语言是一个专用于控制领域的反应式应用的同步编程语言.Esterel语言是系统开发人员描述系统结构和行为的一种形式语言.Esterel语言的并发性使得设计人员集中精力考虑高层次的控制流问题,而不是并发实现的细节.Esterel语言可以检测到控制流错误,传统的编程语言缺乏这种能力.20多年前,它起源于法国的学术界.Berry等开发了Esterel的形式化语义[9],使得Esterel走向实际的应用.
1.2 多目标平台构架
为了解决嵌入式系统开发过程的问题,可以利用抽象层设计的方法,然后将抽象化的方法分别与不同的平台相关的具体实现联系起来,进而实现多目标平台代码的生成.通过对操作系统服务的封装和抽象,使得用户可以在Esterel模型创建过程中基于一致的接口来开发各种嵌入式应用程序,提高这些应用程序在不同系统中的代码重用性,以及在异构的分布式环境下与其他应用系统的互操作性.这种抽象层设计方法的框架如图 1所示.
在抽象设计层中,主要利用Esterel语言建立模型,抽象出软件的行为和需要实现的功能.在此并不涉及与具体平台相关的信息,只需要选择合适的系统模块和系统应用编程接口(Application Programming Interface,API)来实现用户需要的功能.这一层使得软件设计与平台的具体实现相互分离.在抽象层的设计过程中,需要定义从操作系统、分布式应用到硬件驱动等各个层次的标准服务接口,以屏蔽操作系统、网络协议、硬件设备的不同,提高应用系统的互联、互通和互操作能力,实现多目标平台代码的生成.为更好地描述这一过程,用ABRO例子来说明这一设计方法框架.其中A和B分别表示事件A和事件B,R表示重置(Reset)事件,O表示输出(Output).在设计之初,只是考虑抽象的问题;可以根据抽象的问题,画出如图 2所示的状态机.
在这一阶段着重与对问题本身的描述和解决,至于这一问题将被应用于哪个平台则不需要考虑.下一步,可根据状态机,使用Esterel建立模型.Esterel语句描述如下:
module ABRO:
input A,B,R;
output O;
loop
[await A || await B];
emit O
each R
end module
在一般设计中,可能有多个状态机嵌套,设计将被分为不同模块,分别用Esterel来描述.在Esterel建模结束之后,再根据不同的平台,来选择生成针对不同目标设备的平台代码.
值得注意的是,本文方法主要关注操作系统抽象层的设计问题.在操作系统抽象层的建立过程中主要需要解决的问题是:抽象操作系统服务接口.
1.3 多目标平台之间API的统一
解决不同系统之间API接口不一致的主要解决方法有:接口重构和接口模拟.
接口重构是指对基于某一系统开发的应用程序的源码中用到的接口进行修改,使得源码中的接口更改为另一个目标系统的接口.
接口模拟是在程序移植过程中,利用目标系统中的接口模拟出原系统中的接口,使得两个接口在功能上是对等的.接口模拟的过程就是建立一个目标系统API与原系统API的一个对等模拟层,如图 3所示.
为此可以建立一个标准API库,在抽象层的设计中,使用这些标准API进行编程,在这些标准API实现的时候,再利用各系统平台相关的API实现这些标准的API接口.这样,就可以实现一种表述、多种实现的目的了.多平台之间不同API统一的框架如图 4所示.
1.4 多目标平台代码生成过程
Mantis的线程和TinyOS的命令都是用C实现的,但是它们提供的用户编程方式是不一样的.将标准C代码转化为目标平台代码的主要步骤如下:
1) 生成与目标平台对应的main函数和初始化代码.由于TinyOS和Mantis使用不同的编程语言(nesC和ANSI C),造成它们要求的main函数和初始化代码都是不一样的.
2) 将Esterel模型生成的标准C代码整合到目标平台.利用前面Esterel模型编译的结果,可以得到标准C代码(包括.c文件和.h文件).将这些代码分割为不同的代码段,如文件包含、宏定义、函数定义等部分,然后重新将这些代码段构造为TinyOS的应用文件(包括.nc文件和.h文件)和Mantis的应用文件(包括.c文件和.h文件).
3) 将标准C代码中用到的操作系统抽象层提供的标准API替换为平台相关的API.由Esterel模型生成多目标平台代码的流程图如图 5所示.
2 实验构建与分析 2.1 实验用例
本文选用无线传感网络应用的例子来模拟由Esterel模型转换为目标平台代码的过程.无线传感网络应用的功能主要是:系统初始化之后进入睡眠状态,接收数据包事件发生时,由睡眠状态转为运行状态,接收和传输数据包.当接收到第5个数据包时,触发程序的完成事件.这个例子应用包含了传感网络应用的所有的特点:数据包的发送、接收,数据包数据的处理以及睡眠功能.设计初期,根据各个模块的功能设计出相应的状态机,基于此,本文使用Esterel对其进行建模,细节如下.
2.2 TinyOS与Mantis中实现的区别
下面比较在Mantis和TinyOS中这个相同的程序实现上的不同之处:在Mantis当中,程序从一个start函数开始执行,类似于C语言编程中的main函数.可以在start进程中通过调用mos_thread_new函数,派生出新的进程.在新建立的线程中,如算法描述的,state_machine函数每10ms调用一次.这里的CLK事件是通过调用mos_thread_sleep(10)来间接实现的.对接收数据包,需要调用API接口中的com_recv_timed函数.它会启动无线电设备,并进入接收模式一定时间(这里是30 ms).当接收到数据包时,会以收到数据包事件调用state_machine函数(状态机的PKT事件).对发送数据包和切换LED的实现是通过调用com_send和mos_led_toggle以及led_on这样的API实现的.Mantis中的实现框架图如图 6所示.
由图 6可以看出,例子程序在Mantis中实现的结构为:首先是系统文件的包含,随后是对状态机函数中算法的定义;然后是收到数据包,发送数据包,LED控制函数;最后是应用线程的定义,以及在start函数中的线程创建.
TinyOS的编程模型是基于组件的.在TinyOS中例子程序的实现过程如下:首先,周期计时器从Boot.booted事件处理程序中初始化(CLKtimer.startPeriodic).周期计时器的时间周期设定为10 ms.初始化完成之后,一个计时器事件产生(CLKtimer.fired).在这个事件的处理程序当中,状态机被看做一个任务,来处理状态机的CLK事件.由于算法要求无线电设备处于接收状态一定的时间(30 ms),为了在receivePacket方法中实现要求,需要设置一个限时计时器(保持30 ms),并同时启动无线电设备.在这个限时计时器计时时间耗尽时,需要关闭无线电设备(在RXThresholdTimer.fired事件的处理程序中实现).当TinyOS接收到数据包时,会产生一个receive事件(Receive.receive).这个事件的处理程序,实际完成了状态机中有数据包到来事件(PKT事件)的处理工作.对于像非发送数据包这样的行为,状态机调用sendPacket函数来实现.在这个方法当中,首先设置无线电设备为传输状态,并启动它.当无线电设备产生Radio.StartDone事件时,表示无线电设备启动成功,方法内会对无线电是否已启动做出检测.如果无线电设备已经启动,则使用AMSend接口中提供的AMSend.send命令来发送数据包.当数据包发送完时,TinyOS产生一个返回事件AMSend.sendDone来提供发送处理状态的信息.在这个事件的处理程序中,关闭无线电设备.在状态机中,可以使用异步命令来控制LED的状态.TinyOS中例子程序的实现框架如图 7所示.
由上述框架可以得到的例子程序在TinyOS中实现的结构为:首先是用户模块的创建,声明用到的接口,随后是实现部分.在实现当中,首先是在Boot.booted中启动程序中的CLKTimer计时器,从而启动程序,随后定义状态机的函数.然后是发送数据包和接收数据包函数.发数据包中启动无线电设备的返回事件Radio.startDone事件,以及后续的AMSend.sendDone事件,最后的radio.stopDone事件不需要处理,所以没有定义其处理事件.在Boot.booted事件和接收数据包函数中,分别启动了CLKTimer计时器和RXThresTimer计时器,它们分别产生的计时时间到达事件,CLKTimer.fired事件处理程序,以及RXThresTimer事件处理程序.最后是一个LED的控制函数.
2.3 模块划分与模型建立
利用Esterel对上述例子程序进行模块划分和模型建立,可以将例子程序分为:初始化模块,状态机模块,发送、接收数据包模块,LED控制模块.
初始化模块的作用主要是启动用户应用.在Mantis中的主要工作是创建用户线程,并根据要求每睡眠10 ms后,产生CLK信号,检查状态机状态的改变.在TinyOS中的主要工作是启动用户程序,并启动计时器,每隔10 ms产生CLK信号,并检查状态机的状态改变.两者的区别在于:Mantis的应用启动是创建和启动线程,而TinyOS是用Boot.booted启动应用模块.由于都需要进行计时,Mantis是利用线程休眠10 ms,而TinyOS是启动计时器,产生CLKTimer.fired事件进行计时.初始化模块的Esterel模型如下:
module Init
input signal T;output signal CLK;
start_app();
loop
wait(?T);
emit CLK
end
end
状态机模块是程序的核心部分,它决定程序每个时刻的行为.在CLK信号到来时,检测是否进入发送数据包或者接收数据包状态.当PKT信号到来时,检测是否进入程序运行结束状态.然后就是发送或接受完成时,对LED进行控制.状态机的Esterel模型如下:
module Statemachine
input signal CLK,PKT;
loop
[await CLK;Check_State()
||
await PKT;Check_Terminate()]
end
end
数据包发送模块的Esterel模型比较简单,模型中只需要调用SendPacket函数,数据包接收模块的Esterel模型中,要求维持接收状态为30 ms.数据包接收模块的Esterel模型如下:
module ReceivePacket
input signal T;output signal PKT
recv_packet(? T);
if(recv_packet.recev)
then emit PKT
end
LED控制模块主要负责对LED状态进行控制.直接调用led_toggle函数来控制LED.在Mantis中调用mos_led_toggle来进行替换,而在TinyOS中利用led0Toggle、led1Toggle、led2Toggle来进行替换.
2.4 实验结果分析
本文选择前面介绍的通信程序以及一个环境监测的应用作为实验用例.环境监测应用的主要功能是在某节点的监测数据异常时,做出异常警报.主要从生成代码的大小上进行对比.本文以手工编写代码的大小作为基准,分析自动生成代码的相对此基础的变化.利用如下公式进行比较:
式中:Δ表示代码大小增量;AGC(Automatic Generated Code)表示自动生成的代码大小;EOS(Empty OS)表示空操作系统大小;MWC(Manual Written Code)表示手工编写代码的大小;AGC-EOS表示自动生成的应用的大小;MWC-EOS表示手工编写的应用大小.利用该公式得到的代码大小如表 1所示,图 8是Mantis中通信应用和检测应用的代码大小比较.图 9是TinyOS中通信应用和监测应用的代码大小比较.从实验数据中可以看出,自动生成的代码在大小上相对于手工编写的代码是可接受的,基本满足了代码生成的设计要求.操作系统 | 空操作系统/B | 应用 | 手工代码/B | 自动生成代码/B | Δ |
Mantis | 15 650 | 通信应用 | 16 364 | 16 592 | 1.4 |
监测应用 | 17 420 | 18 036 | 3.5 | ||
TinyOS | 1 558 | 通信应用 | 9 826 | 11 242 | 14.4 |
监测应用 | 12 647 | 14 386 | 13.8 |
本文提出了利用并发控制流语言Esterel,对嵌入式系统进行建模.经实验验证表明:
1) 该方法利用抽象层可以实现多平台的代码自动生成.
2) 该方法在实现代码自动生成时具有较优的性能,例如,相对于手工编写代码,自动生成的Mantis应用代码大小的增长小于5%;自动生成的TinyOS应用代码大小的增长小于15%.
为使该方法具有更广泛的适用性,需要进一步对更多的目标平台以及应用类型进行验证.此外,对于代码自动生成的优化算法有待进一步研究.
[1] | Wagner F,Schmuki R,Wolstenholme P,et al.Modeling software with finite state machines:a practical approach[M].Boca Raton:Auerbach Publications,2006:123-144. |
[2] | Samek M. Practical UML statecharts in C/C++ event-driven programming for embedded systems[M].Burlington:Newnes,2008:3-52. |
[3] | Wasowski A. On efficient program synthesis from statecharts[C]// ACM SIGPLAN Conference on Languages,Compilers,and Tools for Embedded Systems.New York:ACM,2003:163-170. |
Click to display the text | |
[4] | Krüger I H,Mathew R,Meisinger M,et al.From scenarios to aspects:exploring product lines[C]//Proceeding of the 4th International Workshop on Scenarios and State Machines:Models,Algorithms and Tools.New York:ACM,2005:1083188. |
Click to display the text | |
[5] | Krüger I H,Mathew R,Meisinger M.Efficient exploration of service-oriented architectures using aspects[C]//Proceeding of the 28th International Conference on Software Engineering.Piscataway,NJ:IEEE Press,2006:62-71. |
Click to display the text | |
[6] | Maoz S,Harel D,Kleinbort A.A compiler for multimodal scenarios:transforming LSCs into aspectJ[J].ACM Transactions on Software Engineering and Methodology,2011,20(4):1757-1770. |
Click to display the text | |
[7] | Maoz S,Harel D.From multi-modal scenarios to code:compiling LSCs into aspectJ[C]//Proceedings of the 14th ACM SIGSOFT International Symposium on Foundations of Software Engineering.New York:ACM,2006:219-230. |
Click to display the text | |
[8] | Caspi P,Pilaud D,Halbwachs N,et al.LUSTRE:a declarative language for programming synchronous systems[C]//14th Symposium on Principles of Programming Languages(POPL'87).New York:ACM,1987:178-188. |
Click to display the text | |
[9] | Berry G,Gonthier G.The Esterel synchronous programming language:design,semantics,implementation[J].Science of Computer Programming,1992,19(2):87-152. |
Click to display the text | |
[10] | Hanxleden R V. SyncCharts in C:a proposal for light-weight,deterministic concurrency[C]//Proceedings of the 7th ACM International Conference on Embedded Software.New York:ACM,2009:225-234. |
Click to display the text | |
[11] | Han G,Natale M D,Zeng H,et al.Optimizing the implementation of real-time Simulink models onto distributed automotive architectures[J].Journal of Systems Architecture,2013,59(10): 1115-1127. |
Click to display the text | |
[12] | Edwards S A. Compiling Esterel into sequential code[C]//Proceedings of the 37th Annual Design Automation Conference.New York:ACM,2000:322-327. |
Click to display the text | |
[13] | Prochnow S,Traulsen C,Hanxleden R V.Synthesizing safe state machines from Esterel[J].ACM SIGPLAN Notices,2006,41(7): 113-124. |
Click to display the text | |
[14] | Halbwachs N,Raymond P,Ratel C.Generating efficient code from data-flow programs[J].Lecture Notes in Computer Science,1991,528(10):207-218. |
Click to display the text | |
[15] | Gérard A,Guatto A,Pasteur C,et al.A modular memory optimization for synchronous data-flow languages:application to arrays in a lustre compiler[C]//Proceedings of the 13th ACM SIGPLAN/SIGBED International Conference on Languages,Compilers,Tools and Theory for Embedded Systems.New York:ACM,2012:51-60. |
Click to display the text | |
[16] | Biernacki D,Colao J,Hamon G,et al.Clock-directed modular code generation for synchronous data-flow languages[J].ACM SIGPLAN Notices,2008,43(7):121-130. |
Click to display the text | |
[17] | 王友瑞,石伟,王志英,等.基于同步EDA工具的异步电路设计流程[J].计算机研究与发展,2012,49(9):2027-2035. Wang Y R,Shi W,Wang Z Y,et al.A novel flow for asynchronous circuit design using synchronous EDA tools[J].Journal of Computer Research and Development,2012,49(9):2027-2035(in Chinese). |
Cited By in Cnki | |
[18] | 吴建国,刘明业,孙元.VHDL语言中断言语句及其综合方法研究[J].计算机学报,1998,21(10):929-932. Wu J G,Liu M Y,Sun Y.Research on assert statement in VHDL and its synthesis methods[J].Chinese Journal of Computers,1998,21(10):929-932(in Chinese). |
Cited By in Cnki (2) | |
[19] | 孙熙,庄磊,刘文,等.一种可定制的自主构件运行支撑框架[J].软件学报,2008,19(6):1340-1349. Sun X,Zhuang L,Liu W,et al.A customizable running support framework for autonomous components[J].Journal of Software,2008,19(6):1340-1349(in Chinese). |
Cited By in Cnki (35) | |
[20] | 接钧靖,史庭训,焦文品,等.自主构件自适应策略的在线定制及动态评估[J].软件学报,2012,23(4):802-815. Jie J J,Shi T X,Jiao W P,et al.Autonomous components whose adaptation policies can be customized online and evaluated dynamically[J].Journal of Software,2012,23(4):802-815(in Chinese). |
Cited By in Cnki (7) | |
[21] | 刘静,何积丰,缪淮扣.模型驱动架构中模型构造与集成策略[J].软件学报,2006,17(6):1411-1422. Liu J,He J F,Miao H K.Strategy for model construction and integration in MDA[J].Journal of Software,2006,17(6):1411-1422(in Chinese). |
Cited By in Cnki (56) | |
[22] | 丁博,王怀民,史殿习,等.一种支持软件可信演化的构件模型[J].软件学报,2011,22(1):17-27. Ding B,Wang H M,Shi D X,et al.Component model supporting trustworthiness-oriented software evolution[J].Journal of Software,2011,22(1):17-27(in Chinese). |
Cited By in Cnki (24) | |
[23] | 许静,司冠南,杨巨峰,等.一个网构软件可信实体模型及基于评估的信任度量[J].中国科学:信息科学,2013,43(1): 108-125. Xu J,Si G N,Yang J F,et al.An internetware dependable entity model and trust measurement based on evaluation[J].Scientia Sinica:Informationis,2013,43(1):108-123(in Chinese). |
Cited By in Cnki (1) | |
[24] | 焦莉,陆维明. 基于共享位置的Petri网系统综合与保性[J].计算机学报,2007,30(3):352-360. Jiao L,Lu W M.Synthesis and property-preservation of Petri net systems based on shared places[J].Chinese Journal of Computers,2007,30(3):352-360(in Chinese). |
Cited By in Cnki (5) | |
[25] | 胡军,于笑丰,张岩,等.基于场景规约的构件式系统设计分析与验证[J].计算机学报,2006,29(4):513-525. Hu J,Yu X F,Zhang Y,et al.Checking component-based designs for scenario-based specifications[J].Chinese Journal of Computers,2006,29(4):513-525(in Chinese). |
Cited By in Cnki (68) | |
[26] | 初佃辉,孟凡超,战德臣,等.基于有限自动机的多层次构件行为匹配模型[J].软件学报,2011,22(11):2668-2683. Chu D H,Meng F C,Zhan D C,et al.Multi-level component behavior matching model based on finite automata[J].Journal of Software,2011,22(11):2668-2683(in Chinese). |
Cited By in Cnki (3) |