张亚航 郭坚 于俊慧
(北京空间飞行器总体设计部,北京 100094)
一种基于非面向对象语言的星载软件构件技术
张亚航 郭坚 于俊慧
(北京空间飞行器总体设计部,北京 100094)
为了进一步提高星载软件复用程度和解决航天器软件开发效率低下的问题,对星载软件特性和软件构件技术进行了分析和研究;对星载软件构件进行了定义,提出了一种基于非面向对象语言的、适用于星载软件开发和应用环境的星载软件构件模型。基于该模型开发的星载软件构件,具备独立性、完整性、可组装性和功能性。除此之外,对基于这种模型的星载软件构件设计、开发和使用方法进行了介绍,可以为采用非面向对象语言进行星载软件构件开发提供参考。在多个型号中对该技术展开实践,实践结果表明:提出的星载软件构件设计方法能够将星载软件开发效率提高2~5倍。
开发效率;构件模型;非面向对象语言;复用;星载软件;航天器
随着我国航天事业的突飞猛进,航天器数量急剧增加,同时航天器星务软件兼顾智能化、自主故障[1]等功能,软件结构越来越复杂。软件复用技术日益成为星载软件系统的规模和航天器软件制造成本的瓶颈。
国内研究者认识到了基于构件的复用技术是软件开发的趋势,也提出了航天器“软件工厂”的概念[2]。然而这些研究主要停留在概念层面,没有明确提出星载软件构件应该具备的特性和形态,也没有提出开发准则。航天领域对构件的认识并不相同,有的研究者认为构件与可复用模块等同[3],有的研究者仍然从结构化编程的角度理解构件,认为构件是一个或多个可复用的函数[4-5]。随着对航天器综合电子软件任务的分析,函数形式的复用难以实现功能级别的封装与复用。而面向对象的理论,可以实现数据与逻辑的封装。本文认为星载软件构件的设计思想仍然应该参考面向对象方法论,并具备封装、多态等特性,这与软件工业界主流的构件技术思路一致[6]。
然而软件工业界的软件构件技术,例如SUN的JavaBean系列标准,OMG的CORBA系列标准和微软的COM系列标准,虽然相对完善和成熟,但由于受到以下条件限制,不能直接应用于航天器综合电子系统:
1)语言环境约束:现有的软件构件设计方法往往基于面向对象语言,而星载软件鉴于任务特点和频繁操作硬件等要求,往往采用汇编或C语言等非面向对象语言进行开发[3-4]。
2)可靠性约束:航天领域要求星载软件具备高可靠性,其遵循的编程规范存在特殊要求,例如不允许内存动态开辟和回收操作。
3)资源约束:星载软件运行环境空间受限,而Java和COM等构件技术,往往需要额外的运行环境确保构件的运行[4]。
与此同时,学术界对非面向对象语言(主要是C语言和汇编语言)构件技术的研究中,或者其构件模型仍然采用结构化设计思想,以函数为颗粒[7],或者需要底层运行环境支持[8-9],或者需要内存动态开辟[10],无法满足航天器软件高可靠性要求。
为此,本文提出星载软件构件定义,明确其应具备的特性和对外接口形态,具备封装、多态等特性,并进一步提出采用非面向对象语言实现星载软件构件的设计和使用方法,用于指导采用非面向对象语言进行星载软件构件设计、开发、组装和使用。最后,对提出的构件模型和开发方法在多个型号展开了工程验证。
不同的文献,对于软件构件往往有不同的定义[11-13],如1995年,Ian.Oraham给出的构件定义如下:构件(Component)是指一个对象(接口规范或二进制代码),它被用于复用,接口被明确定义;而Clemens Szyperski认为,一般来说,构件(Component)是面向软件体系架构的可复用软件模块,其作为可复用的软件组成成份,可被用来构造其他软件。这里,根据星载软件运行特点和需求,参考主流软件构件模型,对星载软件构件进行自我定义,建立星载软件构件模型。
2.1 星载软件构件定义
由于在软件工程领域,对构件的定义并无统一的标准,综合工业界对软件构件的定义和星载软件的特点,本文提出如下定义:
定义1 星载软件构件(本文中有时也将其简称为软件构件或构件),指的是一个可独立发布,并可以由第三方进行组装的功能模块,它满足一定的航天器软件需求,并通过接口提供服务。它应具备四个基本属性:
1)独立性:构件编译时,需与其他构件分离或程序分离,除了基本编译环境,不能依赖构件以外的数据或代码,完成独立编译。
2)完整性:构件发布时,构件使用方不能访问构件内部细节,且不可拆分。
3)组装性:构件实例对外提供可见接口,构件用户能够根据既定规则将构件进行组装。
4)功能性:必须具备具体的、明确的一个或多个功能,能够被用户调用,并在预定的运行环境下正确运行。
为了满足以上定义,本文将星载软件构件分为两类。一类称为静态构件,运行前不需要实例化,以类似于库函数的状态存在,本文中不作详细讨论;另一类称为动态构件,运行前需要进行实例化,是本文讨论的重点。在本文中所说的构件,除了特殊说明外,都指动态构件。
2.2 星载软件构件模型
图1 星载软件构件模型结构 Fig.1 On-board software component model structure
如图1所示,典型的星载软件模型由对外接口、实现体和规约三个要素组成。其中,对外接口是构件向用户提供服务的惟一渠道;实现体为具有一定功能的源程序片段,实现对外接口所提供的服务;规约作为对构件的描述,是构件使用说明书。其中,对外接口和规约对外可见,被用户调用或被阅读;实现体对外不可见,从而保证构件的信息隐藏和独立性。
为了精确描述星载软件构件模型,本文采用BNF范式的扩展范式EBNF[14]对构件模型进行描述:
“< >”表示待描述的语法成分,“::=”表示语法成分定义,“|”表示“或者”关系,“{ }”表示重复1到多次,“[ ]”表示可选项,“( )”表示括号内的成分优先。
则星载软件构件模型满足以下EBNF表达式:
1)<星载软件构件> ::= (<代码体> | <子构件结构>) <对外接口> <构件规约>
2)<对外接口> ::= <主结构体> <初始化接口> [<配置接口>]
3)<构件规约> ::= <构件基本信息> <接口信息> <环境信息> <非功能特性>
4)<子构件结构> ::= {<子构件>}
下面分别对构件三要素进行详细描述:
要素一:对外接口,封装在.h文件中,对外可见,包括主结构体、初始化接口、配置接口。
1)主结构体:规定了构件对象的结构,封装了以下方面的信息。
——构件属性:包括变量和本构件所包含的子构件。
——构件功能接口:提供构件所有对外公开的服务,由用户调用,以函数指针的形式存在。
2)初始化接口:在任何构件运行之前,必须先对主结构体中的各变量赋予初值,即初始化;初始化接口就是提供给构件用户的操作渠道。
3)配置接口(可选):配置接口是可选的对外接口,主要包括两种:与内存配置相关的配置接口,以及构件代码动态编译的相关配置接口。
要素二:实现体,具有一定功能的源程序片段,实现对外接口所提供的服务,对外不可见。构件编写完成后,将源文件编译成二进制文件发布。实现体主要包括:
1)初始化接口的函数体;
2)功能接口的函数体;
3)其他变量和代码片段。
要素三:规约。
规约是对构件的描述,在实现中以.h文件中的注释形式存在。
基于本文第2.1节和第2.2节所述的星载软件构件定义和基本要素,本节以C语言为例,对基于C语言的综合电子软件构件的具体实施规则进行详细描述。
(1)构件实体设计
1)对于某个C语言星载软件构件Component来说,其由一个实现体文件(例如Component.c)和对外接口文件(例如Component.h)组成;
2)构件初始化函数命名规则:Component.c中的初始化函数名称应当为ComponentInit(),其中Component表示构件名称。
(2)对外接口设计
构件所有可见信息都封装在对外接口文件中,对外接口文件包含本构件所有对外接口和构件规约,具体设计为:
1)对外接口文件必须声明本构件的主结构体,主结构体规定了构件对象的结构,从主结构体可以实例化出多个构件对象;
2)对外接口文件必须声明本构件所包含的其他所有子构件SubComponent_1,…,SubComponent_n;
3)对外接口文件必须声明本构件的初始化接口;
4)Component.h文件可能声明本构件的配置接口,其中包括两类配置接口:
——内存分配配置接口:有些构件对象,在运行时需要分配额外的内存空间,但是在某些特定的航天星载软件运行环境中,操作系统无法提供动态内存分配功能。此时,通过在构件主结构体中定义数组的形式进行内存预分配。
——选择编译配置接口:为了实现构件的通用性,构件往往会实现相关功能的最大包络。但是在具体工程中,构件用户根据自身需求,可能只用到该构件提供的部分功能。此时为了降低代码冗余,构件头文件可以以宏定义、选择编译的形式对有效代码进行选择编译。
(3)构件实现体的设计
构件的实现体,一般情况下对用户不可见;实现体中的内容在编写时以代码块或函数体等形式存在,包括初始化接口的函数体、功能接口的函数体,还有其他一些必备的代码:
1)初始化接口的函数体实现,以ComponentInit(参数1,参数2,……)函数形式存在。本函数实现对本构件运行时初始化,必须实现以下功能:
——本构件对象所有属性初始化;
——本构件所包含的所有子构件初始化(如果有子构件,则同样的,子构件初始化包括当前所述的三个功能);
——将本构件主结构体所声明的功能接口与所对应的功能函数挂接。
2)函数体:除了静态构件和初始化函数,其他所有的函数体,其第一个参数必须是指向当前构件实例的指针,例如ComponentFun(struct Component*this_obj,参数1,……)。
3)信息隐藏:构件实现体的任何函数和全局变量,都需声明为对外不可见。
(4)构件规约设计
构件规约作为星载软件构件的使用说明书,由构件设计者提供,向构件用户提供本构件能够使用的一切说明信息。用户将根据这些信息进行构件的选择和使用,其至少需包括:
1)构件基本信息:包括构件的作者、版本、构件名称、发布日期等信息。
2)构件接口信息:包括接口提供的功能、接口名称、接口参数。
3)构件环境信息:包括构件的使用场景、依赖的软件环境、局限性等信息。
4)非功能特性:通常情况下包含该构件的性能及可用性描述。
(5)构件发布
1)所有子构件的文件(包括二进制文件和对外接口文件)与Component文件共同进行编译,形成完整的构件;
2)构件可以向下包含子构件,不同的构件可以包含相同的子构件,但是不得出现构件包含环,如A包含B,B包含C,C包含A;
3)用户使用时,只有构件规约、构件头文件和编译后的二进制文件,构件实现体不向用户提供。
构件组装的任务是在系统框架下,集成已选取的构件形成整个系统,是基于构件软件开发的核心过程。
4.1 直接连接关系(包含与被包含关系)
图2 构件A和B之间关系 Fig.2 Relationship between A and B
本文定义的构件与构件的直接关系,只有包含与被包含关系。这使得构件与构件的关系简洁明了,并保证了构件对用户的独立性和完整性。
如果某个星载软件构件A存在对另外构件B的服务存在直接调用,根据本文第3.1节中星载软件构件独立性原则,构件A必须采用包含子构件的方式,实现对被依赖构件B所提供服务的调用。构件B将作为构件A的一部分(子构件)发布。构件A和构件B采用统一建模语言UML描述,其静态关系如图2所示。
因此,一个基于软件构件的系统或构件的生产过程,实际上是对已有构件的选取、包含和使用。
4.2 间接连接关系(构件连接子)
图3 构件A、B、C之间关系 Fig.3 Relationship among component A, B and C
但是,在一些设计场景下,包含与被包含关系不能完全体现构件之间的关系。考虑一种设计场景:构件A能够对其他一类满足所需特定结构的任意构件对象提供相对通用的服务(例如排序操作)。构件B和构件C都能满足这类特定结构(例如具备优先级和比较能力)。用户或上层构件应用程序希望使用构件A的对象a所提供的服务QuickSort对构件B和构件C的对象进行操作。
此时,构件A、B、C之间的采用统一建模语言UML描述,其静态关系如图3所示。
但是作为构件提供方,如果任意使用构件A提供服务的其他构件,都必须与A作为一个整体发布,存在以下问题:
1)构件A本身难以独立,因为可能存在许多不同的构件对象都需要排序服务,A无法与所有的这些对象都作为整体发布。
2)根据构件独立性原则,显然在构件A发布之后新发布的其他构件将无法再使用A的服务。
3)难以对多个不同类型的构件对象同时进行共同操作。
因此,必须提出一种手段,使得构件A、B、C三者之间不存在包含关系,能够分别独立发布,又能够相互调用彼此的服务。由此,本文引入构件连接子的概念。
定义2 星载软件构件连接子(本文中有时也将其简称为构件连接子或连接子)指的是一种结构,用于描述两个或多个相互独立的构件之间的数据结构关系。连接子没有对应的实现体。
仍然考虑上述场景:通过引入第三方构件连接子X规定该特定结构。构件A在发布的时候,同时发布一种结构连接子X(具备优先级priority属性并通过GetPriority获取和比较方法Compare函数),并宣称任意具备X结构的构件,都能够采用构件A所提供的服务,对连接子X的描述如下:
Connector X
{
Interface1: Compare()
Interface2: GetPriority()
}
构件B和C的提供方在编写B和C的时候,无需知道构件A的具体结构,只需要包含连接子X结构,使得构件B和C具备连接子X的形态。即可令构件B和构件C的对象采用构件A的服务。
当构件B和C类型的某个对象需要构件A的对象所提供的服务时,虽然A、B和C相互独立,即不知道其他两方的任何信息,但是由于他们都知道连接子X的信息,因此可以通过X形成桥梁完成三者的相互左右。典型的步骤如下:
图4 加入连接子X构件A、B、C之间关系 Fig.4 Relationship among componentA, B, C with connector X
步骤一:分别声明构件A的实例a,构件B的实例b,构件C的实例c。
步骤二:将b抽象化成连接子类型的x1。
步骤三:将c抽象化成连接子类型的x2。
步骤四:a对抽象后的连接子元素x1和x2进行操作或提供服务。
步骤五:完成服务后,根据反射机制将x1和x2还原成原有构件类型。
此时,构件A、B、C和连接子X之间的关系如图4所示。注意,图4中某个B的对象只能包含一个X类型数据,对C来说也是如此。构件A对连接子X是依赖关系。通过构件连接子,可以使得构件之间建立联系,进而将软件构件组装成复杂的软件系统,同时各个构件又能够保持各自的独立性。
本方法已经在部分型号任务得到了初步验证。由于工作量和成本限制,难以将同一型号采用不同的手段开发4遍。为了能够对构件应用情况进行分析,本文选取同一产品类型的,包含相同功能项4个的型号任务,且这4个任务由同一团队开发,分别记为任务甲、乙、丙、丁。
其中任务甲采用传统的手工代码编写方式实现软件,任务乙继承甲软件体系结构,部分功能采用构件化设计。任务丙和任务丁在更大范围进行了构件化设计和应用。本节对星载软件构件设计和组装方法在多个型号研制中的试验情况进行分析,并对比型号软件在应用构件化设计方法前后的开发效率和资源消耗情况。相关数据如表1所示。
表1 星载软件构件应用相关数据
5.1 构件化开发技术对型号研制效率的影响分析
图5 多个型号任务中构件应用规模与开发效率关系 Fig.5 Relationship between component utilization and software develop efficiency in Missions
随着软件构件化程度的提高,一般来说研制效率会得到提升。本节将对构件技术相对型号软件研制带来的效率提升实际效果进行分析和说明。
多个型号任务中构件应用规模与开发效率关系如图5所示。可以看出,随着型号中构件复用程度的上升,型号开发的效率越来越高。见效最为明显的是任务甲到乙。从乙到丁开始,随着构件功能覆盖度增加,型号开发效率在仍在不断提高。根据第2.2节中的介绍,型号软件开发时,研制人员需要对需求进行细致的分析,从而选择合适的软件构件,这部分的时间无法省略,因此从乙到丁效率提高趋势会逐步减缓。
如果认为以上型号功能大致在同一等级,则显然,随着构件化技术的深入应用,软件研制速度得到极大提高。
5.2 构件化开发技术对型号代码量分析
图6 复用构件数量和代码总行数趋势 Fig.6 Relationship between component utilization and code linage
由于构件采用了通用化设计,有研究者担心通用设计将带来代码量的提升,进而提高卫星资源(例如PROM)占用度,这里将对实际型号代码量进行统计和分析。
具备类似功能的型号应用构件数量和代码总行数趋势如图6所示。可以看出,随着型号对软件构件复用个数的增加,整星综合电子或数管应用软件的总代码行数不但没有上升,反而呈下降趋势,以任务丙最为明显。这是因为构件代码经过多次复用,往往代码结构经过了多次优化,比较精炼,另外在型号内部构件可以派生多个实例,以实现相同功能(例如需要若干个遥测虚拟信道,只需要声明多个遥测虚拟信道构件实例即可)。
本文提出了一种基于非面向对象语言的星载软件构件设计方法,通过以下手段解决了星载软件运行环境和使用要求对软件构件的需求:
1)本文提出的星载软件构件模型和设计方法完全基于非面向对象语言,但是具备主流构件封装性、独立性、可组装(连接)等特点。
2)结合构件主结构体和配置接口,使得构件能够通过声明主结构体的方式派生构件实例,形成构件实例运行内存,避免了对内存的动态开辟和回收;同时主结构体与实现体的函数指针调用方式,可以通过在轨修改函数指针指向地址,从而轻易实现对构件实例的在轨维护。
3)本文提出的星载软件构件设计方法,完全基于现有的星载软件开发和运行环境,无需安装额外的运行环境。
根据本文的方法开发出了若干星载软件构件,在多个型号任务中展开了应用,并且对应用效果进行了统计和分析。通过分析可以看到,本文提出的星载软件构件设计和实现方法具备以下优点:
1)星载软件构件的可组装性特点,使得大量的功能通过构件组装的形式实现。用户在使用时无需知道构件的内部结构,且只需要根据规约获得构件信息,大大提高了软件开发效率。
2)星载软件构件的独立性,保证了构件代码以构件为粒度完整的复用,被复用的构件无需进行构件内部功能测试,大大提高了代码可靠性,提高了软件质量。
[1] 陈志明, 刘海颖, 叶伟松.“天巡一号”微小卫星星务故障管理设计[J]. 中国空间科学技术, 2014,34(4): 79-83.
CHEN ZHIMING, LIU HAIYING, YE WEISONG. Fault management design of NHTX-1 SAT service system[J]. Chinese Space Science and Technology, 2014, 34(4):79-83.
[2] GUO JIAN,ZHENG XINHUA,ZHANG YAHANG. Produce space software from software factory[C].64thInternational Astronautical Congress,Beijing,2013.
[3] 郭坚, 叶志玲, 陆岚. 星载软件复用技术探讨[J]. 计算机测量与控制, 2007, 15(4):541-546.
GUO JIAN, YE ZHILING, LU LAN. Discussion on technology for onboard software reuse[J]. Computer Measurement & Control, 2007, 15(4):541-546.
[4] 顾斌, 杜建伟, 杨春河. 构件技术在航天器控制软件开发中的应用研究[C]. 2006中国科协年会,北京,2006.
GU BIN, DU JIANWEI, YANG CHUNHE. Research of component in spacecraft control software[C]. 2006 China Science Association Conference,Beijing,2006.
[5] 何熊文, 孙勇. 一种卫星数管中心计算机软件的工程实现[J]. 航天器工程, 2007, 16(5):47-53.
HE XIONGWEN, SUN YONG. Engineering realization of software in central terminal unit of satellite data management system[J]. Spacecraft Engineering,2007, 16(5):47-53.
[6] HAFEDH MILI,FATMA MILI,ALI MILI.Reusing software: issue and research direction[J].IEEE Transactions on Software Engineering, 1995, 21(6):528-535.
[7] 黄奉孝, 高艳华, 张学军. 基于嵌入式构件的编程语言融合技术研究[J]. 计算机工程与设计, 2012, 33(11):4138-4141.
HUANG FENGXIAO, GAO YANHUA, ZHANG XUEJUN. Research on programming language′s syncretic technology based on embedded component[J]. Computer Engineering and Design, 2012, 33(11) : 4138-4141.
[8] MARION POLL F. Object-oriented approach to fast display of electrophysiological data under MS-WINDOWS[J]. Neurosci Methods, 1995, 63:197-204.
[9] MICROSOFT. Advanced COM Interop .NET framework developer′s guide[S]. Microsoft Corporation, 2003. http:∥www.msdn.microsoft.com.
[10] 梅岩, 王力生. 基于构件的嵌入式操作系统开发平台的设计[J]. 计算机工程, 2006, 32(11):97-99.
MEI YAN, WANG LISHENG, Design of component-based embedded operating system development platform[J]. Computer Engineering,2006,32(11):97-99.
[11] SZYPERSKI C, GRUNTZ D, MURER S. Component software: beyond object-oriented programming[M].2nd ed.Beijing:Publishing House of Electronics Industry,2004.
[12] AOYAMA M. Component-based software engineering: Can it change the way of software development[C]∥ Proceedings of the International Conference on Software Engineering, 1998(2):111-120.
[13] BRUCE ECKEL, CHUCK ALLISON. Thinking in C++[M].Beijing:China Machine Press,2004.
[14] WIRTH N. What can we do about the unnecessary diversity of notation for syntactic definition [J]. Communications of the ACM,1977, 20(11): 822-823.
张亚航 1985年生,2010年获北京大学软件工程专业硕士学位,工程师。研究方向为星载软件设计、综合电子、空间信息安全。
(编辑:杨婵)
Research of On-board Software Components Based on Non-object Oriented Language
ZHANG Yahang GUO Jian YU Junhui
(Beijing Institute of Spacecraft System Engineering, Beijing 100094)
In order to further improve the reusability of the on-board software and to solve the problem of the on-board software inefficient development, the characteristics of the spacecraft software and the software component technology were analyzed.Then a definition of the on-board software component was given, and an on-board software component model suitable for spacecraft was proposed based on the non-object oriented language. The on-board software components are independent, integrate, assemble and functional. Besides, the method for the on-board software component design, develop and implement was described. It can be the guide of the on-board software component development based on the non-object oriented language. Some examples were given, in which the software systems were developed according the proposed method.The results show that spacecraft software component development methods are effective, and the spacecraft software development efficiency can be increased by 200%~500%.
Develop efficiency;Component model;Non-object oriented language;Reusability;On-board software;Spacecraft
总装备部预先研究(513200702)资助项目
2014-11-19。收修改稿日期:2015-03-31
10.3780/j.issn.1000-758X.2015.04.006