嵌入式通信软件开发中的设计模式_刘刚
第28卷第6期Vol. 28
No. 6
计算机工程与设计
Computer Engineering and Design
2007年3月Mar. 2007
嵌入式通信软件开发中的设计模式
刘
摘
刚,邵志清,肖立中,梁宏昊
(华东理工大学信息科学与工程学院,上海200237)
要:设计模式描述了在软件开发过程中经常出现的问题及其解决方案,是软件复用的有效途径。在嵌入式系统软件开发中,设计模式的应用可以提高软件的质量。归纳了一个基于客户机/服务器结构的嵌入式通信软件设计模式,并进行了描述,然后给出了该设计模式的一个实现框架。最后通过一个实例表明该框架可以使嵌入式软件开发人员快速的构建许多不同的嵌入式通信软件。
关键词:嵌入式软件; 设计模式; 软件复用; 框架; 客户机/服务器中图法分类号:TP311
文献标识码:A
文章编号:1000-7024(2007) 06-1368-04
Design pattern for embedded communication software development
LIU Gang,
SHAO Zhi-qing,
XIAO Li-zhong,
LIANG Hong-hao
(Department of Computer Science and Engineering, East China University of Science and Technology,
Shanghai 200237, China )
Abstract :Design pattern describes a problem which occurs once and again during the process of software development, and then the solution to that problem is described. Design pattern brings convenience to software reuse. In embedded communication software de-velopment, design pattern is applied to improve the quality of software. In addition to that, a bridge between embedded research and software development is established. A software design pattern which is widely used in embedded communication is brought forward. This pattern is described formally in detail, including its intent, motivation, applicability, structure and consequences, etc. Then an example is given to explain the consequences of this pattern.
Key words :embedded software; design pattern; software reuse; framework; client/server
入式通信软件由于其特定的要求,使其与通用通信软件的开发模式有较大的不同。另外加上嵌入式系统固有的平台性,造成了目前嵌入式系统的通信软件开发中低效重复性工作过多。针对此现状,本文在总结归纳嵌入式通信的常见设计模式后,提出了一个基于客户机-服务器结构的嵌入式通信软件设计模式,并给出了该设计模式的实现框架。最后通过一个实例表明该框架可以使嵌入式软件开发人员快速的构建许多不同的嵌入式通信软件。
0引言
提高软件产品质量、缩短开发周期、降低开发成本是软件开发人员的迫切要求,软件产品的模块化和可复用性是满足这一要求的惟一方法。而面向对象的方法和设计模式[1]的思想是当前实现软件模块化、提高软件可复用性的最优方法。设计模式提供了一种封装设计知识的方法,这些设计知识为标准的软件开发问题提供解决方案。
现在嵌入式系统早已广泛应用于各个领域,这些应用大多数还处于单机使用的嵌入式低层次阶段,其特点是以微控制器(MCU ) 为核心,与一些简单的传感器及监测、伺服控制、指示和显示等设备配合,实现一定的测量、现实、信息处理及控制等功能。但随着3C 的融合和人们可随时随地进入互联网的发展趋势,嵌入式系统模块和嵌入式软件必将会迎来一个飞速发展时期。另外,由于嵌入式系统的通信功能也变得越来越重要,嵌入式通信软件的需求也越来越大。但由于嵌
[2]
1嵌入式通信软件
嵌入式系统主要由微电子芯片(包括微处理器、定时器、
序列发生器、控制器、存储器、传感器等一系列微电子芯片与器件) 以及嵌入式操作系统和应用软件组成。在嵌入式操作系统的基础上,有各种各样的开发环境和相应的通信软件模块,这些软件模块的主要作用是实现通信领域的各种协议和标准,也称为嵌入式通信软件,它是直接建立在硬件平台基础
收稿日期:2006-04-11E-mail :[email protected]
基金项目:国家自然科学基金项目(60373075,60473055) 。
作者简介:刘刚(1979-) ,男,湖北咸宁人,博士研究生,研究方向为软件开发与验证方法嵌入式软件设计;邵志清(1966-) ,男,江苏常熟人,教授,博士生导师,研究方向为软件开发与验证方法;肖立中(1981-) ,男,山东寿光人,博士研究生,研究方向为信息安全;梁宏昊(1983-) ,男,河北石家庄人,硕士研究生,研究方向为软件开发与验证方法、嵌入式软件设计。
-1368-
上的,和硬件密不可分。
嵌入式通信软件由于其开发层次较低,是直接在硬件上开发时间紧要、安全紧要、高可靠性的系统,传统上是C 语言和汇编语言的天下。传统的软件工程技术着重软件的可移植性、可复用性、可伸缩性、易维护性、低成本,借助于一个良好的平台,快速交付,支持业务过程的快速变革的高适应性系统。软件工程使平台以上的系统日臻完善,发展了面向对象技术、构件技术乃至于直接使用软件服务。显然,这与嵌入式系统要处处操心每个软件元件的性能、可靠性、安全性走的是两条路,嵌入式系统开发者不相信臃肿的通用平台能解决他们在有限资源下做出高性能系统所遇到的各种问题。所以,嵌入式系统的开发者一般不关心软件工程技术的最新进展,也很少在他们的工作中采用软件工程新技术。停留在提供完善的模块和子系统层次上,强耦合的过程是模块开发还是现今实时嵌入式系统开发的主流。但从系统的观点来看,嵌入式系统也是系统,特别是硬件技术的快速发展,嵌入式系统软件也有快速适应硬件型号升级问题,也有业务快速变更要求可伸缩、可修改、可复用问题。面向对象技术蓬勃发展在C++上得以体现。于是嵌入式系统自然转向底层是C 的C++。但对象化对实时性、可靠性并没有直接的好处,所以在小型嵌入式应用中,面向对象依然不是主流,仍然是过程是开发方法最后的外衣。尽管如此,有了C++这个桥,为时嵌入式系统再一次和当前软件工程技术合流打下了良好的基础。
面向对象封装带来的松耦合,使它成为分布式可伸缩系统的首选技术。为了参与网络上提供的实时服务,为了支持应用系统的快速变更,快速提供嵌入式产品,大幅度降低成本,提供标准化、构件化产品,嵌入式系统的对象化、构件化势在必行。
中的可复用“积木”组件来进行定制。换句话说,框架是一个可重用软件,实现了一般问题的通用解决方案,它提供了可应用于不同应用程序的公共功能。
在嵌入式系统开发中,经常会遇到本领域特定的一些问题,并且已经形成了有效地解决方案,对其进行归纳总结,建立相应的设计模式,对于嵌入式系统软件开发有着重要的意义。下面的内容重点讨论总结了嵌入式通信软件开发中的设计模式,并给出了实现框架。
3嵌入式通信软件设计模式归纳
在嵌入式通信软件的设计中,考虑到嵌入式系统的特殊
性,一般会选择客户机/服务器体系结构。在嵌入式系统中。通信系统是处在一个分布式环境中,计算又位于不同的嵌入式主机上的程序执行,这些程序一般运行在不同的硬件上,合作完成嵌入式系统的任务。这里可以假定那些为其它程序提供某些服务的程序为服务器,而访问服务器的程序就是客户机。一个嵌入式系统的通信结构中,至少包含一个服务器和一个客户机。当然,服务器和客户机是相对的,在这个嵌入式系统中,它们既可以是服务器,又可以是客户机。
通常,一个设计模式的描述包括以下几个基本部分[4]:①模式名称:描述一个设计问题、它的解法和后果;②模式内容:告诉什么时候要使用该设计模式,解释问题及其背景;③模式结构:描述设计的基本要素,它们的关系,各自的任务以及相互之间的合作;④实现框架:描述该设计模式实现策略。下面遵循Gamma 等人采用的定义模板,给出了一个关于嵌入式通信软件设计模式的范例。
3.13.2
模式名称
基于C/S结构的嵌入式通信软件设计模式。
2设计模式与框架
人们在长期的软件开发实践中,总结出了一些解决特定
模式内容
定义了一个适用于小型嵌入式系统的基于客户机/服务
问题的有效方法,并加以总结提炼,如果再碰到类似的问题时,就可以直接复用以前的方法,这种用以解决类似问题的通用解决方法就是“设计模式”。
最早的的设计模式是Liskov [3]提出的7种基本模式,并提出了对象构成模式的5条基本准则,为面向对象设计模式奠定了理论基础。随后Gamma 等4人[4]借鉴了Alexander 关于建筑结构的模式思想[5],总结了23种常见的软件设计模式,软件设计模式的研究和实践开始逐渐流行起来。简单的说,软件设计模式是对经过实践检验的、好的设计经验的提炼和总结,强调了在特定环境下反复出现的设计问题的一个软件解决方法,侧重于解决软件设计中存在的具体问题。举个例子,设计另外模式对于描述重复出现的“微型结构”(比如反应堆和主动对象) 十分有用,这些微型结构是对一些已被证明可用于
[6]
器体系结构的通信软件设计模式。
3.3模式结构
一般来讲,基于客户机/服务器(C/S) 结构的嵌入式通信系
统中各个部分的交互情况如下:①服务器开始运行;②服务器等待客户机进行连接,这个等待过程可以叫做监听;③客户机开始运行并执行各种操作,其中一些操作需要连接服务器去请求服务;④当一个客户机试图与服务器建立连接时,服务器如果同意则接受该连接;⑤服务器等待来自连接的客户机的消息;⑥当来自客户机的消息到达后,服务器采取某种动作作为响应,然后重新进入等待;⑦客户机和服务器持续以这种方式运行,直到有一方决定断开连接。
图1中表示用UML 顺序图画出了一个嵌入式系统中通信的例子,演示了一个服务器程序同两个客户及程序的通信。
构建分布式通信软件的通用对象结构的抽象。
但是,设计模式是文档化的抽象并不直接产生可复用代码。因此,有必要进行框架的创建和使用[7,8]。通过集成成组的抽象类或模板类,并定义它们的协作的标准途径,框架为应用提供了可复用的软件构件。框架实例化设计模式族,以帮助开发者避免对通用分布式软件组件的昂贵的重新发明。其成果是“半完成”的应用骨架,它可以通过继承和实例化构架
3.4模式实现框架
通过以上分析,本文建立了一个能用来开发任何基于客
户机-服务器结构的嵌入式通信保软件框架,并将其命名为嵌入式通信软件框架(embedded communication software frame-work ,ECSF ) 。ECSF 包含3个类:一个用于实现嵌入式客户机,其它两个用于实现嵌入式服务器的功能。图2描述了在该框架中的类和它们重要的方法。
-1369-
Embedded Server
监听连接
Embedded Client1Embedded Client2
计者承受设很重的质量控制负担。3个关键的控制方法如下:
openConnetction :如果可能,它与在构造函数中(或向下面描述的那样,再后来使用setHost 和setPort ) 指定主机名和端口
连接发送消息
连接
发送响应断开连接
号的服务器进行连接。一旦建立了到服务器的连接,这个方法就启动了一个线程,该线程将一直运行,直到同服务器的连接终止。
sendToServer :如果可能,它向服务器发送消息。该消息可以是任何对象。
发送消息断开连接
closeConnection :它停止和服务器的通信并向线程发送信号,要求线程停止循环,然后终止。
如果失败,上面的3个方法都将抛出IOException 异常—调用者必须以某种方式处理这种情况。
功能访问方法。这些附加的服务方法用于查询客户机的状态并对该状态作微小的改变。它们包括:
isConnected :允许调用者查询客户机当前是否与服务器处于连接状态。
getPort :允许调用着改变已经断开连接的客户机的端口号,为下一次调用openConnetction 作准备。
getHost :允许调用者查询客户机连接着哪个主机或准备连接到哪个主机。
setHost :允许调用者改变已经断开连接的客户机的主机,为下一次openConnetction 作准备。
getInetAddres :提供有关连接的某些详细信息。
EmbeddedServer 类。同EmbeddedClient 一样,EmbeddedSer-ver 有一组共用方法集提供框架中服务器端所有的服务。
公用构造函数。EmbeddedServer 类只有一个构造函数,它获取服务器监听时所使用的端口号。如果需要,可以对端口号进行修改。
公有控制方法。与客户机端相类似,EmbeddedServer 有一组方法,可以被子类用来执行有用的功能。
Listen :创建serverSocket ,对构造函数或setPort 设定得端口进行监听。它还把这个实例作为一个线程启动,该线程在run 方法中持续等待新的客户机请求连接。
Stoplistening :这个方法向run 方法发信号,控制线程体制循环,从而终止线程。除非再次调用listen 方法,否则任何新的客户机都不能被接受。任何处于连接状态的客户机还能够同服务器通信,因为它们的连接受其它现成的控制。
Close :同stoplistening 做的事情一样,但是更彻底。它断开所有处于连接状态的客户机,关闭服务器套接字。
sendToAllClients :它试图给所有客户机发送消息。
Listen 和close 方法都有可能抛出IOException 异常。此方法查询服务器状态并对其做出修改。Islistening :判断服务器是否在监听新的客户机。getClientConnection :返回一个ConnectionToClient 实例的数组。可以使用这个方法编写与所有客户机相关的服务,如搜索具有特殊属性的客户机。对于具体子类的开发人员来说,这是可用的最重要的服务方法之一。
getPort :找出服务器正在监听的端口。
setPort :对于没有在监听的服务器,它只是服务器在下一次listen 被调用时,使用指定端口进行监听。
图1模式顺序
Embedded Client openConnection sendToServer
closeConnection connectionClosed connectionException connectionEstablished haddleMessageFrom Server
Embedded Client sentToClient close setinfo getinfo
Embedded Server listen
stop listening close
sendToAllClients getClientConnection clientConnected clientException listeningException handleMesssageFromClient
*
1
图2模式类图
3.5参与对象类
EmbeddedClient 类。这是一个抽象类,提供了连接服务器
并同其交换对象的所有功能—但是有一个例外,即Embe-ddedClient 必须子类化,目的是具体实现一个方法,该方法在收到来自服务器的消息时采取正确的行动。
EmbeddedClient 实现了Runnable 接口。这是因为可以让它的实例的消息等待活动像先前描述的那样作为一个独立线程运行。作为Runnable 的实现者,EmbeddedClient 有一个run 方法,该方法包含一个在线程生存期内执行的循环,接受来自服务器的消息并对消息做出响应。
EmbeddedClient 的公有接口由服务方法组成,这些方法能够被使用这个类的软件开发人员所访问。
EmbeddedClient 的公有接口包括3类方法:一个构造函数,一些用来控制客户机的方法和一些用来访问客户机基本信息的方法。
公有构造函数。在这个类中只有一个简单的构造函数。它仅仅对表示客户机所要连接的服务器主机名和端口号的变量进行初始化。
公有控制方法。这些方法提供服务,并完成控制客户机的大量工作。它们被声明为Final ,因此不能被子类重载。Final 声明确保子类不能产生有错误的版本。然而,它也意味着子类不能纠正这些方法中的任何涉及纰漏。这一点是框架的设
-1370-
setBacklog :设置队列长度的大小。当队列满的时候,如果一个客户机试图建立连接,则该请求将被拒绝。如果大量的客户机尝试建立连接,队列就可能排满,服务器不能以足够快的速度接受请求。
ConnectionToClient 类。在处于连接状态的时间段内,每个客户机都有一个ConnectionToClient 实例与之对应。就像上面所描述的,这个类的当前实例可以通过getClientConnections 和EmbeddedServer 的几个回调方法访问。可以使用这些对象找到关于客户机的信息并与之进行通信。
ConnectionToClient 是一个具体类。框架的用户只是使用它的功能,并不扩展它。它提供了5个可被EmbeddedServer 的具体子类使用的服务方法。前两个可能会抛出IOException 异常。
sendToClient :用来同客户机进行通信的核心方法。Close :导致客户机连接断开。
getInetAddress :获取客户机连接的因特网地址。setInfo :保存关于客户机的人以信息。例如,具体服务器可以赋予特定客户机特殊权限,用该方法记录该信息。更简单的,这个方法可以用来记录客户机的用户标示符。
getInfo :允许提取已经被setInfo 存储的任何信息。
客户端的EmbeddedDataClient 是EmbeddeClient 的一个子类,它覆盖了一个方法handleDataFromServer ,这个方法除了安排把消息显示给最终用户外,不做任何事。
通过以上实例可以看到通过扩展ECSF 框架来构造基于客户机/服务器结构的嵌入式通信软件相当容易并快捷,这是因为开发者不必在构建软件是从头做起,他直接可以从现有框架中继承父类,然后再添加程序中必须实现的一些功能。这样做的目标都是为了消减一遍又一遍重复开发耗费的巨大费用。如果开发者再遇到类似的通信软件开发时,他应积极地寻找机会,用设计框架来代替设计完整的应用程序。
5结束语
本文提出的设计模式框架ECSF 是一种构建嵌入式通信
软件的完整解决方案,旨在为典型的嵌入式通信软件应用提供分析设计的模型。实践证明这一模式可以有效地提高嵌入式通信软件的开发速度,并使软件的质量得以保证。
嵌入式系统软件面临着规模大、复杂性高而开发周期相对较短,必须具备可定制和演化的能力等挑战,因此借鉴重用性高、扩展性和维护性好的设计模式思想来进行嵌入式系统软件开发显得非常必要。广义上讲,一个设计模式可以是一个算法、一种数据结构,但是在实践中,特别是在面向对象设计方法中,模式一般由一组协作的类构成,可以解决特定的问题。在嵌入式系统软件开发过程中,归纳并应用设计模式,可以较好的实现软件复用,提高软件生产率[9]。同时便于将嵌入式系统理论研究结果进行形式化、半形式化的规范描述,在嵌入式系统理论和嵌入式系统软件实现之间建立起一座桥梁。
4一个实例
通过上面介绍的嵌入式通信框架的组成类,开发者很容
易的创建嵌入式通信软件。具体步骤如下:创建框架中抽象类的子类;在这些子类中,书写框架类中声明为抽象的某些方法的实现;在应用程序的不同部分,调用框架所提供的公有方法,这些方法是框架的服务,允许应用程序设计者控制客户或服务器并找到关于它们的信息。
为了演示ECSF 的使用,本文通过一个简单的例子来演示它的使用。在高速公路无障碍收费系统中,要求将由摄像机和地感线圈测出的信号通过一个嵌入式单元传给中央嵌入式系统,并计算其收费情况,然后返回给该嵌入式单元,完成收费。这是个典型的基于客户机/服务器结构嵌入式软件。本文将其称为SimpleCharge (用Java 程序实现) 。图3显示了利用ECSF 框架来构建SimpleCharge 应用程序的类图。
SimpleCharge 程序的服务器所作的所有事情就是接受测试客户机传来的数据并计算出应收费金额并将其传回客户机,所以称之为EmbeddedCenterServer ,从图3可以看出,它是Em-beddedServer 的一个子类。这个类本身没有用户界面,它的进程一旦启动,想停止就必须被杀死,否则将无休止的运行。方法handleDataFromClient 还作了一件事,即为了送回计算结果而调用sendToAllClient 方法。另一个最主要的方法count 就是进行计算以得到返回给客户机的收费金额。
>
display
EmbeddedClient
EmbeddedServer
参考文献:
[1][2][3][4][5]
孙鸣. 使用设计模式改善程序结构[R ]. 北京:IBM developer-Works, 2001.
沈连丰, 宋铁成, 叶芝慧, 等. 嵌入式系统及其开发应用[M ]. 北京:电子工业出版社, 2005.11-12.
Liskov B,Guttag J.Abstraction and specification in program de-velopment [M ].New York:McGraw-Hill, 1986.5-9.
Gamma E. 设计模式:可复用面向对象软件的基础[M ]. 北京:机械工业出版社, 2000.1-2.
Alexander C,Ishikawa S,Silverstein M,et al.A pattern language:Towns, buildings, construction [M ]. New York:Oxford Univer-sity Press, 2001.3-4. [6][7][8]
Douglass B P. 实时设计模式[M ]. 北京:北京航空航天大学出版社, 2004.120-124.
Noble J, Weir C.Small memory software:Patterns for systems with limited memory [M ].Boston:Addison-Wesley, 2001.56-48. Schmidt D C,Stal M,Rohnert H,et al. Pattern-oriented software architecture:Patterns for concurrent and networked objects, V olu-me 2[M ]. New York:Wiley &Sons, 2000.36-37. [9]
Jacobson I. Software reuse-architecture and organization for business success [M ].New York:ACM Press, 1997.33-34. [10]张克非. 嵌入式实时操作系统分析[J ]. 计算机工程与设计,
2005,26(8) :2020-2022.
charge Console
accept
display
charge client handle Message From Server Send Message To Server
charge Server
handle Message From Client count main
图3利用ECSF 框架来构建SimpleCharge 应用程序
-1371-