一、 嵌入式系统高级语言编程特点
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广,易于维护。因此高级语言编程具有许多优势。
(1) 通用性强。随着微处理器技术的不断发展,其功能越来越具体,种类越来越多,而不同种类的微处理器都有自己专用的汇编语言。这就为系统开发者设置了一个巨大的障碍,使得系统编程更加困难,软件重用无法实现;而高级语言一般和具体机器的硬件结构联系较少,比较流行的高级语言对多数微处理器都有良好的支持,通用性较好。
(2) 容易编程。随着嵌入式系统应用范围的不断扩大和应用层面的不断深入,系统规模越来越大,结构越来越复杂,设计变得越来越困难。一个系统内有多种微处理器已是常见的事情。这时,要用汇编语言编程不仅要求编程人员要对所有微处理器的汇编语言都了如指掌,而且随着任务复杂程度的不断提高,用汇编语言实现规模较大的任务难度极大;而高级语言的语意层次较高,且有丰富的程序库支持,因此,编写较复杂的程序相对简单。使用高级语言编程,不仅能够加快系统开发进程,节省大量时间,同时也有利于系统调试及维护工作。
(3) 容易阅读。由于汇编语言的语意层次较低,在阅读汇编语言程序时,往往要花费大量精力分析“细节”问题,如为什么把一个数据传送给一个寄存器,为什么把某个标志位清零等。当把注意力放在这些“细节”上的时候,往往又把程序的主线忘记了。因此,汇编语言程序不仅难写,而且难读。采用高级语言就可以很好地解决这些问题。因为高级语言的语意层次较高,表达方式更接近人们日常的思维方法,一些数学表达式可以直接用一条语句表达,程序的思路更加清晰、简捷。因此,程序也就容易阅读。
(4) 可移植性好。由于汇编语言和具体的微处理器密切相关,为某个微处理器设计的程序不能直接移植到另一个不同种类的微处理器上使用,因此,移植性差;而高级语言对所有微处理器都是通用的,因此,程序可以在不同的微处理器上运行,可移植性较好。这是实现软件重用的基础。
(5) 可维护性好。高级语言程序往往是模块化设计,各个模块之间的接口是固定的。因此,当系统出现问题时,可以很快地将问题定位到某个模块内,并尽快得到解决。另外,模块化设计也便于系统功能的扩充和升级。
(6) 直接支持中断管理。中断是嵌入式系统最重要也是最常用的信息交换方式,因此中断系统是否灵活,中断功能是否强大对系统的性能影响极大。在高级语言中,一般都有强大的中断管理机制,以便构建高效灵活的中断系统;而在汇编语言中,一般要由程序设计者自己编程来进行中断管理。这不仅增加了编程的难度,而且效果也不一定好。
(7) 支持软件重用。由于汇编语言的可移植性极差,使得其软件重用性严重受阻;而高级语言具有较好的通用性和可移植性,这就使得高级语言程序可以在不同时间、不同地点、不同系统、不同人员之间分享,实现软件重用。这不仅可以提高产品质量,缩短开发周期,降低产品成本,而且还可以使软件开发走上正规化、产业化的道路。
二、 嵌入式系统高级编程语言概述
在过去40多年,人们开发研制了几十种计算机语言,但是仅有少数几种得到了广泛应用。这就提示我们选择一个合适的语言系统并不容易。在小型嵌入式系统中,通常只有一个微处理器,并且其主要工作往往不是计算,而是控制,应选择控制能力较强的语言。在大型嵌入式系统中,往往会有多个微处理器或计算机并行工作,构成多机系统。它们中有些工作于真正的嵌入式模式,有的则为纯粹的信息处理。此时,对系统的编程就变得相当复杂,不同的任务可能会用不同的语言编程。因此,大型系统往往是一个多语言系统。对于这种“混合”系统的语言选择更应慎重考虑。
目前,在嵌入式系统开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。本文选择了Ada、C/C++、Modula-2作为讨论对象,并对Java作简要介绍。
Ada语言是20世纪70年代美国国防部开发并投入使用的功能强大的通用系统开发语言,最初为Ada83。它支持模块化、独立编译、协处理等功能。其可靠性、可维护性、可读性都是相当好的。后来,为了更好地支持OOP(Object-Oriented Programming),对其进行了改进,形成了目前广泛使用的Ada95。使用Ada语言可以大大改善系统的清晰性、可靠性、可维护性等性能指标[2,3]。它是美国国防部指定的唯一一种可用于军用系统开发的语言。
C语言是由Dennis Richie于1972年在AT&Bell实验室研究成功并投入使用的系统编程语言。其设计目标是使C既具有汇编语言的效率,又具有高级语言的易编程性。其最具代表性的应用是UNIX操作系统。从20世纪80年代中期C语言涉足实时系统后,受到了普遍欢迎。目前是使用最广泛的嵌入式系统编程语言。C++是由Bjarne Stroustrup 于1995年在Bell实验室研制成功并投入使用的。C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语言程序性能差一些。
Modula-2是由Nicklans Wirth在70年代后期根据Pascal 和Modula开发的系统设计语言。其主要目标是在模块化、系统编程、协同处理等方面对Pascal 进行改进。Modula-2具有很强的类型检查能力和丰富的低级功能支持。因此,可用它设计一个完整的实时程序而不用汇编语言的支持。Modula-3是1988年由DEC(Digital Equipment Company)和ORC(Olivetti Research Center)根据Modula-2开发研制并投入使用的系统开发语言。目标是设计一个功能强大但结构简单的通用编程语言。它在协同处理、OOP、自动垃圾收集以及对C语言和UNIX的支持等方面对Modula-2进行了改进。
考察一门语言是否适用,需要从多个方面进行考虑。不同语言,都有自己的特色。很难将其全面进行比较。另外,任何一门语言的运行特性都与运行环境密切相关,因此,选择语言时,应综合考虑。为叙述方便,我们把语言的性能划分为基本性能和运行性能两个方面进行分析。
(1) 基本性能
一门语言的基本性能主要是指语言本身的固有特性,或称静态特性,即构成语言的组成部分所具有的特性。它不仅决定着语言的可用性、适用性、可靠性等,而且对应用程序的开发产量、便携性、可维护性、安全性也有一定影响。它是一门语言的核心和基石。考查语言的基本性能主要从以下几个方面入手:与汇编语言/机器语言的接口,直接寻址,对硬件的控制,位操作,中断处理,指针操作,数据类型的支持及检测,控制结构的支持及检测,模块化支持,独立编译支持,任务结构支持,异常事件处理,数学模型支持,语法和整体结构,多任务支持,标准程序库,面向对象编程(OOP)结构等。
(2) 运行性能
语言的运行性能是指其应用软件在实际运行时所表现出来的行为特点,是一门语言的动态特性。它对语言的适用性、实用性及可用性影响极大。主要表现在任务期限设置、代码执行时间的简单评价,调度策略选择,时序分析支持等几个方面。由于语言的运行性能和运行环境密切相关,如CPU速度、内存大小、硬盘速度、操作系统、编译环境等。因此,评价语言的运行性能应和具体的应用环境联系起来,任何理论上的评价都没有多大的实际意义。故本文不再讨论这方面的内容。
三、 常用嵌入式系统高级编程语言基本性能
一门语言的基本性能是组成这门语言的基本要素,是决定其性能好坏的关键因素。因此,认真研究语言的基本性能是非常必要的。下面对上述几种流行的嵌入式系统编程语言的基本性能进行简单的分析和比较。
(1) 与汇编语言和机器代码的接口
在Ada语言中,可以通过子程序功能实现对汇编语言及机器代码的访问。标准程序包MACHINE-CODE支持这一功能。在C中,汇编语言可以定义为一个asm模块嵌入在C源代码中,也可以编写成一个独立的外部进程,用功能调用进行通讯。宏(Macros)也可以用来提供汇编语言操作。语言本身没有提供这方面的机制,由编译器提供支持。
(2) 直接寻址
Ada通过SYSTEM包中的Address类寻址绝对地址;C/C++ 通过指针完成绝对寻址,在C++中也可以通过Peek、Poke操作完成存储器寻址;Modula-2 通过SYSTEM模块支持绝对寻址。
(3) 对硬件的访问和控制
Ada通过表述从句把Ada代码映射到具体器件;C/C++通过指针完成对硬件的操作;在Modula-2中器件被标识为具有绝对地址的对象,通过赋值语句访问这些对象。
(4) 位操作
Ada 具体的位可以在表述从句中指明,多个独立位也可组成一个逻辑字,通过逻辑操作对它们进行加工处理。位操作是C的强项,逻辑操作、移位操作均可实现位操作;在C++中,还可以通过定义“bitfields”结构实现更多的位操作功能。Modula-2用“SET”结构处理位操作。在嵌入式应用中最有用的结构是“BITSET”,通过它可以方便地实现各种位操作。
(5) 中断处理
Ada通过中断处理任务实现中断处理。一个中断任务和一个中断矢量密切相关,在中断矢量地址处存放中断任务入口地址。C/C++语言本身没有提供标准的中断处理机制,用户可以自行处理。Modula-2通过SYSTEM模块中的IOTRANSFER进程实现中断处理。用户也可以编写自己的中断处理程序。
(6) 指针
三种语言都提供了较强的指针操作。
(7) 数据类型检测
Ada 有严格的数据类型检测机制,混合类型是禁止的,数据类型的转换是允许的,但有严格的规范。C语言的数据类型检测功能较弱,在数据类型转换时可能会出现错误,C++有改进。Modula-2 对数据类型检测严格,不允许不明确的数据类型转换。
(8)程序控制结构
Ada 提供了一整套严格的程序控制结构以支持分支、循环等功能,也支持无条件转移;C/C++提供了分支、循环等控制结构,方便灵活,但在使用时应注意避免不安全因素;Modula-2在分支、循环控制方面是很严格的,但在使用CASE-ELSE结构时应注意,在无条件转移时,用EXIT跳出循环,用RETURN结束进程,使用时应多加小心。
(9) 模块结构与独立编译
Ada程序的基本单元是subprogram、package、task和generic,而编译的基本单元是subprogram和package,所有程序单元都可以独立编译,类型检查严格,没有公用数据区。C程序的基本单元是function,外部变量是全局变量,内部变量是局部变量;C++程序是若干编译文件的集合,每个文件可以定义class、function全局变量等类型,每个文件可以独立编译。Modula-2 的主程序由若干程序模块和库模块组成,程序模块是程序单元的最高层,各模块可独立编译。
(10) 异常事件处理
Ada提供了一个综合错误处理机制,用于处理由于语言本身和用户自己引起的异常事件;C/C++语言没有提供直接的异常事件处理机制,需由用户自己处理,C++(V3.0)提供直接的异常事件处理功能;PIM Modula-2不提供异常事件处理功能,但也有一些其它编译系统提供运行错误检测和处理机制。
(11) 任务(task)结构支持
“task”是Ada程序标准的组成模块,是该语言重要的和不可分割的组成部分;C中没有独立的“task”结构,但可以通过“function”实现;在C++中可以通过“classes”实现;Modula-2中没有独立的“task”结构,可以用“PROC”结构实现。
(12) 数学模型支持
Ada提供了较好的数学模型支持,无论在何种微处理器上运行,其程序行为都会受到严格检查;C/C++支持定点、浮点运算。但数学模型并不完善,容易引起一些无定义的行为,如被0除或上下溢出等;PIM Modula-2的数学模型与运行环境有联系,新标准在改进。
(13) 语法与结构
Ada英语式结构及语法,程序易读易懂;C/C++是一种简洁(terse)语言,程序比较难读,C++更难读;Modula-2语言结构定义明确,程序容易阅读。
(14) 多任务支持
多任务支持是Ada语言的一大特点,是其不可分割的组成部分;C/C++不支持多任务;Modula-2通过“Coroutines”等机制支持多任务。
(15) 标准库
Ada有丰富的基本功能库;C/C++有非常丰富的库程序,但在应用中应当注意兼容性;Modula-2有比较丰富的库程序,但也应注意兼容性。
(16) OOP结构支持
Ada83就是一个OOP语言,Ada95又有增强;C不支持OOP,C++具有较强的OOP功能;Modula-2不支持OOP,Modula-3支持OOP。
四、 关于Java
Java语言是Sun Microsystems公司于1995年在Internet上发布的面向对象的程序设计语言。其主要研制人是Gosling。他的目标是设计一个能够运行于规模巨大、地域分布、体系异构的网络环境中的语言系统,完成多个电子设备之间的通讯与协同工作。Gosling在设计中采用了虚拟机器码(virtual machine code)方式,即Java语言编译后产生的是虚拟机,虚拟机运行在一个解释器上,解释器用来解释Java编译器编译后的程序。这使得Java成为一个与平台无关的计算机语言,即Java应用程序不用修改即可在不同的软硬件平台上运行。从而实现了“一次编程,到处可用”(Write once,Run anywhere),使得Java语言很快风靡全球,甚至有人说是一场革命。
(1) Java的特点
Java语言是一种网络语言,但它又不仅仅局限于此。近两年Java语言发展迅速,在很多领域得到广泛使用。这说明Java确实具有鲜明的特色。
首先,Java是简单的。它删除了一些高级语言不是绝对必要的东西,如运算符重载、标题文件、指针运算、隐式类型转换、多重继承等,并通过自动垃圾收集功能大大简化了程序设计者的内存管理工作,使程序设计变得简单。
第二,Java是面向对象的。Java语言的设计集中于对象及其接口,它提供了简单的类机制及动态的接口模型。对象中封装了它的状态变量及相应的方法,实现了模块化和信息隐藏;而类则提供了一类对象的原型,并通过继承机制使子类可以使用父类的方法,实现代码重用。
第三,Java的体系结构是中立的。一般来说,网络是由不同结构的机器构成,CPU和作业结构均有不同。让应用程序在不同结构的机器上运行是一件困难的事;但Java编译器能产生一种结构中立的目标文件格式,使编译码可以在不同的处理器上运行。
第四,Java是健全的。Java在编译和运行程序时都要对可能出现的问题进行检查,以防止错误的产生。当程序出现例外时,Java会把它抛弃,以保证计算机系统不会崩溃。
第五,Java是安全的。Java不支持指针操作,避免了指针操作带来的种种弊端。Java拥有多个阶层的互锁(interlocking)保护措施,能有效防止病毒的侵入和破坏行为的发生。字节码验证被Web浏览器用来确保小程序不含病毒。
第六,Java是多线程的。Java可以同时执行多个线程,如它可以在进行计算的同时与用户交互对话。通常,编写多线程程序是困难的;但Java提供了容易使用的同步机制,使程序设计方便容易。
第七,Java是可扩展的。Java的设计使它能够适应不断发展的环境。在类库中可以自由地加入新的方法和实例变量而不影响用户程序的执行,同时,Java通过接口来支持多重继承,使之比严格的类继承具有更灵活的方式和更大的扩展性。
(2) Java与嵌入式系统
Java是网络语言,而嵌入式系统则在功能、价格、体积、功耗、上市时间等方面有特殊要求。因此Java语言受速度和代码容量的限制,本身并不适合于嵌入式系统的应用。但Sun公司并不愿意放弃这个发展潜力巨大的应用市场,对Java进行改进后发表了J2ME(Java2 Micro Edition)。它是Java API的一个子集,只包含了Java的关键特性,是专门针对对内存具有苛刻要求的嵌入式系统而设计的。J2ME粗略地将应用对象划分为两大类:内存在128KB“512KB之间的设备和内存大于512KB的设备,根据不同的类别提供不同的用户接口和软件包。
但是由于嵌入式系统的特殊性,一些在Java语言中被认为是特性优异的东西却在嵌入式系统中成了十分棘手的问题。如缺乏指针寻址和运行于Java虚拟机模式中的安全特性都使Java很难对硬件进行直接控制;自动垃圾收集功能使应用失去了实时决策能力,即它不能以可预知、可重复的时间长度来处理一个具体的代码部分。实际上Java在进行垃圾收集时暂停了整个应用程序的执行,因此,开发人员几乎不能控制垃圾收集的时间。令人鼓舞的是这些问题已经或正在被解决。即时编译(just-in-time-compiler)程序和预先编译(ahead-of-time-compiler)程序都可以提高Java代码的执行速度。如New Monic公司的Real Time Executive和WindRiver公司的Fast J都可以在一定程度上保证绝对时间决策应用的开发。
另一方面,为能够从硬件上更好地支持Java,很多厂家都致力于Java芯片的开发研制,以充分发挥嵌入式Java小巧灵活的特点来开拓嵌入式市场。如HP公司正在开发、完善自己的编译工具和Java虚拟机。其目的是要Java嵌入到如打印机、医学监视器、自动取款机等设备中,使设备具有一定的智能,增加设备的可管理性和可用性,大大提高设备的工作效率。Sun公司宣称将在J2ME中以Profile的形式为每个领域规定API组件。Java TV就是其中面向双向数码电视的API组件。Sun表示,Java TV技术将提供双向电视所需的基本环境、安全性、扩展性及可携带性。通过Java TV技术,开发人员可以开发出更加富有吸引力的信息内容和服务。Sun还宣布,将和通用汽车公司达成合作伙伴关系,共同致力于汽车工业Java标准的确立。一旦Java成为汽车工业的电脑标准语言,Java将增加数百万用户。在过去的一年里,J2ME在无线通讯领域得到了充分的重视和广泛的应用。因为J2ME中包含了能够在大多数消费者的设备中运行的Java虚拟机、专用的API函数库和用于开发和设置的工具。因此,手机生产商纷纷推出能够上网的手机供用户选用。
在控制系统中,Java可以使所有操作在由标准Web浏览器提供的面板上完成。这些控制面板就是Java Applet。Web浏览器可以用来监视或设置系统。这些监视和设置操作均可以通过网络远程进行,这使得系统更加容易管理,特别是那些设置在危险的、遥远的或不易接近地区的设备尤其需要Java的介入。
Java不仅是一门语言,更是一种思想。它将使软件开发在设计风格、设计方法、设计目标、设计过程等方面发生根本性变化。它将成为软件再实现的基础,未来OS的核心,各种应用软件的开发平台和实现环境。但Java并不是万能的,它有自己的应用范围,在网络管理、网络应用、面向对象的应用、可视化操作、交互式应用领域Java是优秀的;但在实时控制领域,如火箭控制、传感器控制、宇宙飞行器的方位控制等方面C或汇编语言依然是最佳选择。
总结
近年来计算机语言发展很快。新的语言不断产生;流行语言不断改进,逐步完善;不适用的语言逐步被淘汰。计算机语言的发展呈现出生机勃勃的景象。随着嵌入式技术的发展,嵌入式系统高级编程语言倍受重视,逐步形成了百花齐放,百家争鸣的局面。未来的嵌入式系统编程语言谁主潮流,现在还很难预测。Ada语言定义严格,易读易懂,有较丰富的库程序支持,目前在国防、航空、航天等相关领域应用比较广泛,未来仍将在这些领域占有重要地位。C语言具有广泛的库程序支持,目前在嵌入式系统中是应用最广泛的编程语言,未来仍将在嵌入式系统应用领域占重要地位。C++在PC机系统和工作站系统中都是重要的编程语言。Visual C++将在图形用户接口——GUI方面有较大作用。但C++的目标代码往往比较庞大和复杂,在嵌入式系统应用中应充分考虑这一因素。Modula-2定义清晰,支持丰富,具有较好的模块化结构,在教学科研方面有较广泛的应用。虽然该语言的开发应用一直比较平缓,但近两年在欧洲有所复苏。Java语言相对年轻,但发展势头强劲。它的“一次编程,到处可用”的特性使得它在很多领域倍受欢迎。随着网络技术和嵌入式技术的不断发展,Java及嵌入式Java的应用也将越来越广泛。
从运行特性来说,Ada语言具有较好的运行行为。因为它和运行环境联系较少,语言本身定义严格,因此其运行行为是比较出色的。C/C++语言程序的运行行为和硬件环境及编译系统有较大联系,因此,可能会产生较多意想不到的问题。在某个环境下运行的程序换个机器或换个编译系统就可能会产生错误。因此,无论是C还是C++都有几页无定义行为的说明。 Modula-2也有比较好的运行行为,且仍在改进。Java语言采用虚拟机技术,使得其应用程序的运行与具体的应用平台无关,因此,具有良好的运行特性。
虽然我们仅仅讨论了Ada、C/C++、Modula-2三种语言的基本特性,对Java语言做了简要介绍。但这足以提示我们在嵌入式系统开发应用中,应高度重视高级语言在嵌入式系统编程中的优势所在,并应合理地选择、研究、开发、应用适合自己的嵌入式系统高级编程语言。这不仅是未来嵌入式系统开发应用的发展方向,而且对我国的嵌入式技术发展意义重大。
一、 嵌入式系统高级语言编程特点
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广,易于维护。因此高级语言编程具有许多优势。
(1) 通用性强。随着微处理器技术的不断发展,其功能越来越具体,种类越来越多,而不同种类的微处理器都有自己专用的汇编语言。这就为系统开发者设置了一个巨大的障碍,使得系统编程更加困难,软件重用无法实现;而高级语言一般和具体机器的硬件结构联系较少,比较流行的高级语言对多数微处理器都有良好的支持,通用性较好。
(2) 容易编程。随着嵌入式系统应用范围的不断扩大和应用层面的不断深入,系统规模越来越大,结构越来越复杂,设计变得越来越困难。一个系统内有多种微处理器已是常见的事情。这时,要用汇编语言编程不仅要求编程人员要对所有微处理器的汇编语言都了如指掌,而且随着任务复杂程度的不断提高,用汇编语言实现规模较大的任务难度极大;而高级语言的语意层次较高,且有丰富的程序库支持,因此,编写较复杂的程序相对简单。使用高级语言编程,不仅能够加快系统开发进程,节省大量时间,同时也有利于系统调试及维护工作。
(3) 容易阅读。由于汇编语言的语意层次较低,在阅读汇编语言程序时,往往要花费大量精力分析“细节”问题,如为什么把一个数据传送给一个寄存器,为什么把某个标志位清零等。当把注意力放在这些“细节”上的时候,往往又把程序的主线忘记了。因此,汇编语言程序不仅难写,而且难读。采用高级语言就可以很好地解决这些问题。因为高级语言的语意层次较高,表达方式更接近人们日常的思维方法,一些数学表达式可以直接用一条语句表达,程序的思路更加清晰、简捷。因此,程序也就容易阅读。
(4) 可移植性好。由于汇编语言和具体的微处理器密切相关,为某个微处理器设计的程序不能直接移植到另一个不同种类的微处理器上使用,因此,移植性差;而高级语言对所有微处理器都是通用的,因此,程序可以在不同的微处理器上运行,可移植性较好。这是实现软件重用的基础。
(5) 可维护性好。高级语言程序往往是模块化设计,各个模块之间的接口是固定的。因此,当系统出现问题时,可以很快地将问题定位到某个模块内,并尽快得到解决。另外,模块化设计也便于系统功能的扩充和升级。
(6) 直接支持中断管理。中断是嵌入式系统最重要也是最常用的信息交换方式,因此中断系统是否灵活,中断功能是否强大对系统的性能影响极大。在高级语言中,一般都有强大的中断管理机制,以便构建高效灵活的中断系统;而在汇编语言中,一般要由程序设计者自己编程来进行中断管理。这不仅增加了编程的难度,而且效果也不一定好。
(7) 支持软件重用。由于汇编语言的可移植性极差,使得其软件重用性严重受阻;而高级语言具有较好的通用性和可移植性,这就使得高级语言程序可以在不同时间、不同地点、不同系统、不同人员之间分享,实现软件重用。这不仅可以提高产品质量,缩短开发周期,降低产品成本,而且还可以使软件开发走上正规化、产业化的道路。
二、 嵌入式系统高级编程语言概述
在过去40多年,人们开发研制了几十种计算机语言,但是仅有少数几种得到了广泛应用。这就提示我们选择一个合适的语言系统并不容易。在小型嵌入式系统中,通常只有一个微处理器,并且其主要工作往往不是计算,而是控制,应选择控制能力较强的语言。在大型嵌入式系统中,往往会有多个微处理器或计算机并行工作,构成多机系统。它们中有些工作于真正的嵌入式模式,有的则为纯粹的信息处理。此时,对系统的编程就变得相当复杂,不同的任务可能会用不同的语言编程。因此,大型系统往往是一个多语言系统。对于这种“混合”系统的语言选择更应慎重考虑。
目前,在嵌入式系统开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。本文选择了Ada、C/C++、Modula-2作为讨论对象,并对Java作简要介绍。
Ada语言是20世纪70年代美国国防部开发并投入使用的功能强大的通用系统开发语言,最初为Ada83。它支持模块化、独立编译、协处理等功能。其可靠性、可维护性、可读性都是相当好的。后来,为了更好地支持OOP(Object-Oriented Programming),对其进行了改进,形成了目前广泛使用的Ada95。使用Ada语言可以大大改善系统的清晰性、可靠性、可维护性等性能指标[2,3]。它是美国国防部指定的唯一一种可用于军用系统开发的语言。
C语言是由Dennis Richie于1972年在AT&Bell实验室研究成功并投入使用的系统编程语言。其设计目标是使C既具有汇编语言的效率,又具有高级语言的易编程性。其最具代表性的应用是UNIX操作系统。从20世纪80年代中期C语言涉足实时系统后,受到了普遍欢迎。目前是使用最广泛的嵌入式系统编程语言。C++是由Bjarne Stroustrup 于1995年在Bell实验室研制成功并投入使用的。C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语言程序性能差一些。
Modula-2是由Nicklans Wirth在70年代后期根据Pascal 和Modula开发的系统设计语言。其主要目标是在模块化、系统编程、协同处理等方面对Pascal 进行改进。Modula-2具有很强的类型检查能力和丰富的低级功能支持。因此,可用它设计一个完整的实时程序而不用汇编语言的支持。Modula-3是1988年由DEC(Digital Equipment Company)和ORC(Olivetti Research Center)根据Modula-2开发研制并投入使用的系统开发语言。目标是设计一个功能强大但结构简单的通用编程语言。它在协同处理、OOP、自动垃圾收集以及对C语言和UNIX的支持等方面对Modula-2进行了改进。
考察一门语言是否适用,需要从多个方面进行考虑。不同语言,都有自己的特色。很难将其全面进行比较。另外,任何一门语言的运行特性都与运行环境密切相关,因此,选择语言时,应综合考虑。为叙述方便,我们把语言的性能划分为基本性能和运行性能两个方面进行分析。
(1) 基本性能
一门语言的基本性能主要是指语言本身的固有特性,或称静态特性,即构成语言的组成部分所具有的特性。它不仅决定着语言的可用性、适用性、可靠性等,而且对应用程序的开发产量、便携性、可维护性、安全性也有一定影响。它是一门语言的核心和基石。考查语言的基本性能主要从以下几个方面入手:与汇编语言/机器语言的接口,直接寻址,对硬件的控制,位操作,中断处理,指针操作,数据类型的支持及检测,控制结构的支持及检测,模块化支持,独立编译支持,任务结构支持,异常事件处理,数学模型支持,语法和整体结构,多任务支持,标准程序库,面向对象编程(OOP)结构等。
(2) 运行性能
语言的运行性能是指其应用软件在实际运行时所表现出来的行为特点,是一门语言的动态特性。它对语言的适用性、实用性及可用性影响极大。主要表现在任务期限设置、代码执行时间的简单评价,调度策略选择,时序分析支持等几个方面。由于语言的运行性能和运行环境密切相关,如CPU速度、内存大小、硬盘速度、操作系统、编译环境等。因此,评价语言的运行性能应和具体的应用环境联系起来,任何理论上的评价都没有多大的实际意义。故本文不再讨论这方面的内容。
三、 常用嵌入式系统高级编程语言基本性能
一门语言的基本性能是组成这门语言的基本要素,是决定其性能好坏的关键因素。因此,认真研究语言的基本性能是非常必要的。下面对上述几种流行的嵌入式系统编程语言的基本性能进行简单的分析和比较。
(1) 与汇编语言和机器代码的接口
在Ada语言中,可以通过子程序功能实现对汇编语言及机器代码的访问。标准程序包MACHINE-CODE支持这一功能。在C中,汇编语言可以定义为一个asm模块嵌入在C源代码中,也可以编写成一个独立的外部进程,用功能调用进行通讯。宏(Macros)也可以用来提供汇编语言操作。语言本身没有提供这方面的机制,由编译器提供支持。
(2) 直接寻址
Ada通过SYSTEM包中的Address类寻址绝对地址;C/C++ 通过指针完成绝对寻址,在C++中也可以通过Peek、Poke操作完成存储器寻址;Modula-2 通过SYSTEM模块支持绝对寻址。
(3) 对硬件的访问和控制
Ada通过表述从句把Ada代码映射到具体器件;C/C++通过指针完成对硬件的操作;在Modula-2中器件被标识为具有绝对地址的对象,通过赋值语句访问这些对象。
(4) 位操作
Ada 具体的位可以在表述从句中指明,多个独立位也可组成一个逻辑字,通过逻辑操作对它们进行加工处理。位操作是C的强项,逻辑操作、移位操作均可实现位操作;在C++中,还可以通过定义“bitfields”结构实现更多的位操作功能。Modula-2用“SET”结构处理位操作。在嵌入式应用中最有用的结构是“BITSET”,通过它可以方便地实现各种位操作。
(5) 中断处理
Ada通过中断处理任务实现中断处理。一个中断任务和一个中断矢量密切相关,在中断矢量地址处存放中断任务入口地址。C/C++语言本身没有提供标准的中断处理机制,用户可以自行处理。Modula-2通过SYSTEM模块中的IOTRANSFER进程实现中断处理。用户也可以编写自己的中断处理程序。
(6) 指针
三种语言都提供了较强的指针操作。
(7) 数据类型检测
Ada 有严格的数据类型检测机制,混合类型是禁止的,数据类型的转换是允许的,但有严格的规范。C语言的数据类型检测功能较弱,在数据类型转换时可能会出现错误,C++有改进。Modula-2 对数据类型检测严格,不允许不明确的数据类型转换。
(8)程序控制结构
Ada 提供了一整套严格的程序控制结构以支持分支、循环等功能,也支持无条件转移;C/C++提供了分支、循环等控制结构,方便灵活,但在使用时应注意避免不安全因素;Modula-2在分支、循环控制方面是很严格的,但在使用CASE-ELSE结构时应注意,在无条件转移时,用EXIT跳出循环,用RETURN结束进程,使用时应多加小心。
(9) 模块结构与独立编译
Ada程序的基本单元是subprogram、package、task和generic,而编译的基本单元是subprogram和package,所有程序单元都可以独立编译,类型检查严格,没有公用数据区。C程序的基本单元是function,外部变量是全局变量,内部变量是局部变量;C++程序是若干编译文件的集合,每个文件可以定义class、function全局变量等类型,每个文件可以独立编译。Modula-2 的主程序由若干程序模块和库模块组成,程序模块是程序单元的最高层,各模块可独立编译。
(10) 异常事件处理
Ada提供了一个综合错误处理机制,用于处理由于语言本身和用户自己引起的异常事件;C/C++语言没有提供直接的异常事件处理机制,需由用户自己处理,C++(V3.0)提供直接的异常事件处理功能;PIM Modula-2不提供异常事件处理功能,但也有一些其它编译系统提供运行错误检测和处理机制。
(11) 任务(task)结构支持
“task”是Ada程序标准的组成模块,是该语言重要的和不可分割的组成部分;C中没有独立的“task”结构,但可以通过“function”实现;在C++中可以通过“classes”实现;Modula-2中没有独立的“task”结构,可以用“PROC”结构实现。
(12) 数学模型支持
Ada提供了较好的数学模型支持,无论在何种微处理器上运行,其程序行为都会受到严格检查;C/C++支持定点、浮点运算。但数学模型并不完善,容易引起一些无定义的行为,如被0除或上下溢出等;PIM Modula-2的数学模型与运行环境有联系,新标准在改进。
(13) 语法与结构
Ada英语式结构及语法,程序易读易懂;C/C++是一种简洁(terse)语言,程序比较难读,C++更难读;Modula-2语言结构定义明确,程序容易阅读。
(14) 多任务支持
多任务支持是Ada语言的一大特点,是其不可分割的组成部分;C/C++不支持多任务;Modula-2通过“Coroutines”等机制支持多任务。
(15) 标准库
Ada有丰富的基本功能库;C/C++有非常丰富的库程序,但在应用中应当注意兼容性;Modula-2有比较丰富的库程序,但也应注意兼容性。
(16) OOP结构支持
Ada83就是一个OOP语言,Ada95又有增强;C不支持OOP,C++具有较强的OOP功能;Modula-2不支持OOP,Modula-3支持OOP。
四、 关于Java
Java语言是Sun Microsystems公司于1995年在Internet上发布的面向对象的程序设计语言。其主要研制人是Gosling。他的目标是设计一个能够运行于规模巨大、地域分布、体系异构的网络环境中的语言系统,完成多个电子设备之间的通讯与协同工作。Gosling在设计中采用了虚拟机器码(virtual machine code)方式,即Java语言编译后产生的是虚拟机,虚拟机运行在一个解释器上,解释器用来解释Java编译器编译后的程序。这使得Java成为一个与平台无关的计算机语言,即Java应用程序不用修改即可在不同的软硬件平台上运行。从而实现了“一次编程,到处可用”(Write once,Run anywhere),使得Java语言很快风靡全球,甚至有人说是一场革命。
(1) Java的特点
Java语言是一种网络语言,但它又不仅仅局限于此。近两年Java语言发展迅速,在很多领域得到广泛使用。这说明Java确实具有鲜明的特色。
首先,Java是简单的。它删除了一些高级语言不是绝对必要的东西,如运算符重载、标题文件、指针运算、隐式类型转换、多重继承等,并通过自动垃圾收集功能大大简化了程序设计者的内存管理工作,使程序设计变得简单。
第二,Java是面向对象的。Java语言的设计集中于对象及其接口,它提供了简单的类机制及动态的接口模型。对象中封装了它的状态变量及相应的方法,实现了模块化和信息隐藏;而类则提供了一类对象的原型,并通过继承机制使子类可以使用父类的方法,实现代码重用。
第三,Java的体系结构是中立的。一般来说,网络是由不同结构的机器构成,CPU和作业结构均有不同。让应用程序在不同结构的机器上运行是一件困难的事;但Java编译器能产生一种结构中立的目标文件格式,使编译码可以在不同的处理器上运行。
第四,Java是健全的。Java在编译和运行程序时都要对可能出现的问题进行检查,以防止错误的产生。当程序出现例外时,Java会把它抛弃,以保证计算机系统不会崩溃。
第五,Java是安全的。Java不支持指针操作,避免了指针操作带来的种种弊端。Java拥有多个阶层的互锁(interlocking)保护措施,能有效防止病毒的侵入和破坏行为的发生。字节码验证被Web浏览器用来确保小程序不含病毒。
第六,Java是多线程的。Java可以同时执行多个线程,如它可以在进行计算的同时与用户交互对话。通常,编写多线程程序是困难的;但Java提供了容易使用的同步机制,使程序设计方便容易。
第七,Java是可扩展的。Java的设计使它能够适应不断发展的环境。在类库中可以自由地加入新的方法和实例变量而不影响用户程序的执行,同时,Java通过接口来支持多重继承,使之比严格的类继承具有更灵活的方式和更大的扩展性。
(2) Java与嵌入式系统
Java是网络语言,而嵌入式系统则在功能、价格、体积、功耗、上市时间等方面有特殊要求。因此Java语言受速度和代码容量的限制,本身并不适合于嵌入式系统的应用。但Sun公司并不愿意放弃这个发展潜力巨大的应用市场,对Java进行改进后发表了J2ME(Java2 Micro Edition)。它是Java API的一个子集,只包含了Java的关键特性,是专门针对对内存具有苛刻要求的嵌入式系统而设计的。J2ME粗略地将应用对象划分为两大类:内存在128KB“512KB之间的设备和内存大于512KB的设备,根据不同的类别提供不同的用户接口和软件包。
但是由于嵌入式系统的特殊性,一些在Java语言中被认为是特性优异的东西却在嵌入式系统中成了十分棘手的问题。如缺乏指针寻址和运行于Java虚拟机模式中的安全特性都使Java很难对硬件进行直接控制;自动垃圾收集功能使应用失去了实时决策能力,即它不能以可预知、可重复的时间长度来处理一个具体的代码部分。实际上Java在进行垃圾收集时暂停了整个应用程序的执行,因此,开发人员几乎不能控制垃圾收集的时间。令人鼓舞的是这些问题已经或正在被解决。即时编译(just-in-time-compiler)程序和预先编译(ahead-of-time-compiler)程序都可以提高Java代码的执行速度。如New Monic公司的Real Time Executive和WindRiver公司的Fast J都可以在一定程度上保证绝对时间决策应用的开发。
另一方面,为能够从硬件上更好地支持Java,很多厂家都致力于Java芯片的开发研制,以充分发挥嵌入式Java小巧灵活的特点来开拓嵌入式市场。如HP公司正在开发、完善自己的编译工具和Java虚拟机。其目的是要Java嵌入到如打印机、医学监视器、自动取款机等设备中,使设备具有一定的智能,增加设备的可管理性和可用性,大大提高设备的工作效率。Sun公司宣称将在J2ME中以Profile的形式为每个领域规定API组件。Java TV就是其中面向双向数码电视的API组件。Sun表示,Java TV技术将提供双向电视所需的基本环境、安全性、扩展性及可携带性。通过Java TV技术,开发人员可以开发出更加富有吸引力的信息内容和服务。Sun还宣布,将和通用汽车公司达成合作伙伴关系,共同致力于汽车工业Java标准的确立。一旦Java成为汽车工业的电脑标准语言,Java将增加数百万用户。在过去的一年里,J2ME在无线通讯领域得到了充分的重视和广泛的应用。因为J2ME中包含了能够在大多数消费者的设备中运行的Java虚拟机、专用的API函数库和用于开发和设置的工具。因此,手机生产商纷纷推出能够上网的手机供用户选用。
在控制系统中,Java可以使所有操作在由标准Web浏览器提供的面板上完成。这些控制面板就是Java Applet。Web浏览器可以用来监视或设置系统。这些监视和设置操作均可以通过网络远程进行,这使得系统更加容易管理,特别是那些设置在危险的、遥远的或不易接近地区的设备尤其需要Java的介入。
Java不仅是一门语言,更是一种思想。它将使软件开发在设计风格、设计方法、设计目标、设计过程等方面发生根本性变化。它将成为软件再实现的基础,未来OS的核心,各种应用软件的开发平台和实现环境。但Java并不是万能的,它有自己的应用范围,在网络管理、网络应用、面向对象的应用、可视化操作、交互式应用领域Java是优秀的;但在实时控制领域,如火箭控制、传感器控制、宇宙飞行器的方位控制等方面C或汇编语言依然是最佳选择。
总结
近年来计算机语言发展很快。新的语言不断产生;流行语言不断改进,逐步完善;不适用的语言逐步被淘汰。计算机语言的发展呈现出生机勃勃的景象。随着嵌入式技术的发展,嵌入式系统高级编程语言倍受重视,逐步形成了百花齐放,百家争鸣的局面。未来的嵌入式系统编程语言谁主潮流,现在还很难预测。Ada语言定义严格,易读易懂,有较丰富的库程序支持,目前在国防、航空、航天等相关领域应用比较广泛,未来仍将在这些领域占有重要地位。C语言具有广泛的库程序支持,目前在嵌入式系统中是应用最广泛的编程语言,未来仍将在嵌入式系统应用领域占重要地位。C++在PC机系统和工作站系统中都是重要的编程语言。Visual C++将在图形用户接口——GUI方面有较大作用。但C++的目标代码往往比较庞大和复杂,在嵌入式系统应用中应充分考虑这一因素。Modula-2定义清晰,支持丰富,具有较好的模块化结构,在教学科研方面有较广泛的应用。虽然该语言的开发应用一直比较平缓,但近两年在欧洲有所复苏。Java语言相对年轻,但发展势头强劲。它的“一次编程,到处可用”的特性使得它在很多领域倍受欢迎。随着网络技术和嵌入式技术的不断发展,Java及嵌入式Java的应用也将越来越广泛。
从运行特性来说,Ada语言具有较好的运行行为。因为它和运行环境联系较少,语言本身定义严格,因此其运行行为是比较出色的。C/C++语言程序的运行行为和硬件环境及编译系统有较大联系,因此,可能会产生较多意想不到的问题。在某个环境下运行的程序换个机器或换个编译系统就可能会产生错误。因此,无论是C还是C++都有几页无定义行为的说明。 Modula-2也有比较好的运行行为,且仍在改进。Java语言采用虚拟机技术,使得其应用程序的运行与具体的应用平台无关,因此,具有良好的运行特性。
虽然我们仅仅讨论了Ada、C/C++、Modula-2三种语言的基本特性,对Java语言做了简要介绍。但这足以提示我们在嵌入式系统开发应用中,应高度重视高级语言在嵌入式系统编程中的优势所在,并应合理地选择、研究、开发、应用适合自己的嵌入式系统高级编程语言。这不仅是未来嵌入式系统开发应用的发展方向,而且对我国的嵌入式技术发展意义重大。
举报