1、Java语言与嵌入式
对于选用嵌入式编程语言,一般说,越是高级的语言,其编译和运行库施加的开销越大,你的应用程序也越大,越慢。已经公认用汇编语言能写出最小最快的程序,其次是用C或Forth,接下来较大的是C++或Basic,然后才是Java。因此一般来说,编程人员都会首选汇编和C,而然后才会考虑C++或Java。
但是嵌入式开发者为何要来关注Java呢?笔者以为,随着不断增长的市场需求,很多嵌入设备必须适应网上交流的需要,为了迎合此要求,考虑这种到开发Internet应用程序的便利,众多开发者都发现使用这种语言是有意义的。另一个原因是随着内存条及32位处理器价格的下降,最初在嵌入系统使用Java太昂贵的问题不再有了。随着使用Java的成本代价减少,它的很多优点应当被考虑作为嵌入平台。
2、Java对于嵌入式的优点分析
Java语言的优点在于:它当初就是由理解和信奉网络计算梦想的一个小巧而专注的开发组设计的,虽然该语言最初的实施方案有点缺陷,有许多后来已被解决了,但为了这个梦想,他们很少在技术上妥协,结果诞生了一种专为以相互通讯为主要目的的设备而设计的语言。
有许多技术上的优点都可能会引导嵌入系统开发者选择Java,以下就是这些优点(其中有几个也适用于通用编程)
A)与处理器无关
Java的第一个优点就是与处理器无关,这个优点似乎与嵌入式系统没什么相干。传统上,嵌入程序就是针对特定的微处理器设计并在其上运行的,而C语言程序的可移植性则可通过编译或交叉编译来保障。
但是在Sun公司的模型中,一个程序可能是存储在一个系统上,而被下载并运行在另一个完全不同的系统上;设备可能从不同地方下载一些程序来在一个处理器上运行,或者不同的处理器运行一个程序,通过网络在相互间传递数据。使用Java,一个嵌入式系统就可能成为一个通用的通信设备,能下载并运行能完成特定任务的程序。
对嵌入式系统,这是一个新的模型,已经有一些开发者正在向它靠拢。例如,电视机机顶盒的供应商已宣布并入JVM,以使用户能通过Javaapplets在他们观看电视的同时接收到的支持该电视节目的一些内容。这样你在观看足球比赛时,看到的支持内容就可以是对球员的技术统计;若你在看电影,看到的支持内容就可以是演员的背景资料。JVM还被并入到移动电话中,这样用户可接收股票报价信息、比赛分数及其他即时信息。
笔者以为,这是一个恰当的设计和实施模型。其一是你在选择开发平台时更加灵活了。你无需在与目标相同的平台上开发,也不用去关心交叉编译,因为Java字节码能在任何有JVM的操作系统中运行;另一个优点是:几乎所有的检测和调试可以独立于目标设备来进行。但是,一些数据输入和硬件交互要求在目标(或是很好的仿真系统)上测试。由于个别JVM有时有兼容性的问题,你应该在所有将用到该程序的平台上测试它。但一般来说,你并不要高级而昂贵的、配备有逻辑探针、ICE以及其它调试工具的、针对目标平台的开发环境。
B)面向对象的编程
Java是一种纯粹面向对象的语言。所有代码和数据都是某个类的一部分,没有全局变量或是独立于类存在的代码,一个对象是一个类的实例,对象是通过调用操作方法,或者说函数来操作的,而这些方法或函数也是类的一部分,对象的方法就对象的数据进行操作。Java类被组织成一个等级层次,在层次结构中,一个子类能够继承其超类的行为,并可用子类所具备的一些特有功能来扩展其超类的功能。对象模型是你能定义对应真实事物的数据结构,使得程序的任务和任务如何实现者二者之间的转换变得基本上透明。
面向对象的设计和编程的优点在于其开发速度和代码的可维护性,许多面向对象的开发都能通过利用和更改现存类库来完成,而不是创造一个新的结构,这就使开发加快了,例如,一个硬件开关能在软件中使用一个开关对象来实现,该对象包含用于控制和操作开关的所有必需的数据和代码。面向对象的方法还尽量使用自然的结构,使其有很高的可读性,且可轻易更改和加强。
C)安全和安全操作
由于有了JVM,一个Java应用程序与操作系统或硬件完全隔绝,因此计算机病毒或其它作祟的的代码就很难获得对设备的控制。虚拟机是主机设备和那些可能难以确定其质量和可靠性的软件之间的一个保护层。
另外,Java设计者从该语言中去掉了指针变量的概念。Java不能任意访问其内存位置,它们只能读写有Java内存分配管理系统创建的对象。由于Java编译器所强制的严格的分类机制,从理论上来说,访问那些未分配给程序的内存区域是不可能的。这个限制使得要写恶意代码的程序变得非常困难了。
对Javaapplet施加的限制就更加严格了。由于Javaapplet被设计成从Internet上下载,因而被视为不可信任的代码,除非它包括你已认定为可信任的主机的数字指纹。JVM在内存的一个称之为sandbox的区域运行诸如applet这种不可信任的代码。它给每个applet分配资源和特权,并将其限定在这些分配区域范围中。
D)内存管理
Java的内存管理远比其他语言简单,因为它不使用指针。当对象被实例化时,内存被动态分配。正如我们前面分析的,对个别内存地址的访问被Java的设计者视为一个对安全的潜在危险,因此,访问也被禁止。而且,Sun的网络模型已假定你也许不知道目标处理器,而引用专用内存地址变得没有必要。去掉指针的结果不仅提高了安全性,还简化了编程,错误也减少了。
在C语言中,可以用值或引用的方式来访问数据。事实上,出于灵活性和控制考虑,非原始数据类型都由引用方式来存取,即通过指针访问。因此,值和引用的不同变得非常清楚,特别是:因为你不得不使用不同的符号(*和&)来存取数据。要用这两种不同的访问方式,你必须清楚理解它们是什么以及你为什么应该使用这一个,而不使用那一个。
在Java中,由值和引用来存储是无缝的,尤其因为其符号都一样。两者间唯一不同在于数据类型本身:所有原始数据类型始终由值的方式存取;所有对象,包括字串、数组以及文件流,始终由引用方式访问。声明为原始数据变量类型包含该变量的值,声明为对象的变量则包含对该对象(即该对象的地址)的一个引用,而非对象自身的引用。仅仅声明一个对象变量并不给对象分配内存,你必须用“new”关键字来分配内存和创建对象。
这两种方法最根本的不同在于:不可能象在C中那样就Java内存地址做指针算术或其他操作。Java中对象的地址是相对的(或虚拟的),它由虚拟机任意分配,因此你没有理由还想要指针地址。
E)垃圾收集
垃圾收集自动收集内存中未引用的内存,并将其归回空闲内存链表中。JVM使用此功能将不在使用的内存还给系统。
当Java程序说明并实例化一个对象或数组时,它仅仅做一个JVM请求,访问其下面的系统内存(通常是通过主机操作系统)并分配内存,Java的垃圾收集系统通过内存收集对象,然后检查它们的引用链。Java的垃圾收集系统的工作方式一般是搜索内存中的对象,然后检查它们的引用表。它计算程序中有多少变量当前正在引用每个对象。若对象的引用数目为零,它知道此对象不再在使用了,它的内存可以收回。其结果就是,不必像你在C语言所作的那样,要人工来释放分配的内存。在C中,释放内存是一个必要、耗时且易出错的细节。Java自动而精确的处理此过程,去除了C/C++程序中那种常见的错误致因。
F)网络
由于今天的嵌入式系统通常都是网络的,采用内置网络支持的语言节约了在实现网络协议和通信程序方面耗费的大量时间和努力。在Java中,网络类包括TCP/IP流和使用TCP及UDP的数据报程序,用于HTTP和URL服务的操作方法,以及错误检查代码和恢复功能。
虽然实现网络也可能用其他语言,比如C语言,但那些语言要求特别的附件软件包,DLL,或其他必须由操作系统,或者第三方销售提供程序模块,特别附件通常要求有操作系统或第三方工具的知识,不象Java,有标准的、内置的网络支持。
Java包括网络包出于必要,因为设计者不能对一个作为基础的操作系统的网络设施做任何假定,他们必须得包括集成网络程序库,以确保Java程序能在所有平台上工作。
G)动态配置
动态配置是指一系统启动时的用户制定配置或重新配置。需载入特殊的硬件配置、网络参数或在引导期间支持特定用途的一些实用程序的系统,常常使用动态配置。
Java以动态捆绑来支持动态配置。当你组成一个程序的各个类文件编译成字节码时,在你的类文件之间,或者对JVM包的类(如图形、网络以及核心语言支持)引用,还没有被解决。当JVM载入你的程序时,它动态的载入并捆绑(即链接)你的程序引用的所有的类。因此,要改变系统配置,你所需要做的一切就是修正相应的类文件。下一次系统时,JVM自动捆绑新文件到你的程序中,而新的配置将生效执行。
H)异常处理
与许多操作系统和程序不同,对嵌入系统而言,重新启动通常是无法接受的,就像我们都不希望打电话或者看电视时突然有技术性的中断一样。这意味着实际上所有嵌入式系统都必须足够坚实以截取错误来防止它们使程序或更糟的是使整个设备崩溃。
程序错误的致因很多。相对来说,很少是因为继承逻辑错误,而大多数程序的崩溃是因为意外输入,或者是因为程序不能调用系统资源来完成某个特定操作。
在Java中,由抛出(产生)一个异常来提示错误。使用专门为异常处理而设计的语句(关键字try、catch、和finally),程序就能将其错误处理代码安排到几个集中区域,try程序块是程序执行的正常流程。当一个异常发生在try块(包括该嵌套块中的各层子程序)中,控制就交给了catch块。不管是否有异常发生,finally块中的代码始终要被执行。未被处理的异常会由调用堆栈自下而上传播JVM并终止程序。你不再需要动手编程,来将错误状态通过几层函数调用返回。而是,在错误发生由检测错误的代码直接抛出一个异常。这极大地简化了应用程序中的错误处理代码,进而获得更好地错误处理效果和更坚实可靠的代码。
I)线程
大多数操作系统都给一个过程产生和管理多个线程的能力,这些线程彼此独立地完成不同地任务。但是,很少由程序语言提供对线程管理的直线支持,通常都需要直接调用操作系统功能。Java却相反,直接在语言提供了产生、管理和协调同步线程地功能。与Java的其他特点一样,该功能是必要的,因为设计者不敢确定底层的操作系统是否支持多线程。
开发者越来越多的在程序中使用线程,将其作为满足一个程序不能完成的,通常相互无关的一些任务的一种手段。由于Java对线程有内置语言支持,以Java创建多线程较之与其它语言更简单、更自然。
J)图形
JVM包括一个庞大的图形及窗口支持程序包,称为AbstractWindowingToolkit(AWT)。用AWT,你能在应用程序中快速而轻易地创建精致而强大的图形用户界面。对于需要精细的用户界面的嵌入系统来说,AWT能节省大量开发时间,从而是产品更快的走向市场。