摘要:基于嵌入式系统的概念,阐述嵌入式系统的关键技术、嵌入式开发以及广泛的应用。首先,分析嵌入式系统的技术特点,分别从嵌入式处理器和嵌入式操作系统两方面介绍,着重说明它不同于其它操作系统的一些处理方法和过程;在此基础上阐述嵌入式软件的开发过程,并结合作者嵌入式软件开发的实践,着重阐述嵌入式软件的一些开发技巧。接着,介绍目前嵌入式系统一些流行的应用,以及南京东大移动互联技术有限公司自行研制的基于蓝牙技术的嵌入式产品。最后,给出作者的体会,展望嵌入式系统的前景。
关键词:嵌入式系统 嵌入式处理器 微内核 内存管理单元 蓝牙系统
引 言
在当前数字信息技术和网络技术高速发展的后PC(Post-PC)时代,嵌入式系统已经广泛地渗透到科学研究、工程设计、军事技术、各类产业和商业文化艺术以及人们的日常生活等方方面面中。随着国内外各种嵌入式产品的进一步开发和推广,嵌入式技术越来越和人们的生活紧密结合。
1970年左右出现了嵌入式系统的概念,此时的嵌入式系统很多都不采用操作系统,它们只是为了实现某个控制功能,使用一个简单的循环控制对外界的控制请求进行处理。当应用系统越来越复杂、利用的范围越来越广泛的时候,每添加一项新的功能,都可能需要从头开始设计。没有操作系统已成为一个最大的缺点了。
C语言的出现使操作系统开发变得简单。从上世纪80年代开始,出现了各种各样的商用嵌入式操作系统百家争鸣的局面,比较著名的有VxWorks、pSOS和Windows CE等等,这些操作系统大部分是为专有系统而开发的。另外,源代码开放的嵌入式Linux,由于其强大的网络功能和低成本,近来也得到了越来越多的应用。
1 嵌入式系统的技术特点
嵌入式系统通常包括构成软件的基本运行环境的硬件和操作系统两部分。嵌入式系统的运行环境和应用场合决定了嵌入式系统具有区别于其它操作系统的一些特点。
(1)嵌入式处理器 嵌入式处理器可以分为三类:嵌入式微处理器、嵌入式微控制器、嵌入式DSP(Digital Signal Processor)。嵌入式微处理器就是和通用计算机的微处理器对应的CPU。在应用中,一般是将微处理器装配在专门设计的电路板上,在母板上只保留和嵌入式相关的功能即可,这样可以满足嵌入式系统体积小和功耗低的要求。目前的嵌入式处理器主要包括:PowerPC、Motorola 68000、ARM系列等等。
嵌入式微控制器又称为单片机,它将CPU、存储器(少量的RAM、ROM或两者都有)和其它外设封装在同一片集成电路里。常见的有8051。
嵌入式DSP专门用来对离散时间信号进行极快的处理计算,提高编译效率和执行速度。在数字滤波、FFT、谱分析、图像处理的分析等领域,DSP正在大量进入嵌入式市场。
(2)微内核结构
大多数操作系统至少被划分为内核层和应用层两个层次。内核只提供基本的功能,如建立和管理进程、提供文件系统、管理设备等,这些功能以系统调用方式提供给用户。一些桌面操作系统,如Windows、Linux等,将许多功能引入内核,操作系统的内核变得越来越大。内核变大使得占用的资源增多,剪裁起来很麻烦。
大多数嵌入式操作系统采用了微内核结构,内核只提供基本的功能,比如:任务的调度、任务之间的通信与同步、内存管理、时钟管理等。其它的应用组件,比如网络功能、文件系统、GUI系统等均工作在用户态,以系统进程或函数调用的方式工作。因而系统都是可裁减的,用户可以根据自己的需要选用相应的组件。
(3)任务调度
在嵌入式系统中,任务即线程。大多数的嵌入式操作系统支持多任务。多任务运行的实现实际是靠CPU在多个任务之间切换、调度。每个任务都有其优先级,不同的任务优先级可能相同也可能不同。任务的调度有三种方式:可抢占式调度、不可抢占式调度和时间片轮转调度。不可抢占式调度是指,一个任务一旦获得CPU就独占CPU运行,除非由于某种原因,它决定放弃CPU的使用权;可抢占式调度是基于任务优先级的,当前正在运行的任务可以随时让位给优先级更高的处于就绪态的其它任务;当两个或两个以上任务有同样的优先级,不同任务轮转地使用CPU,直到系统分配的CPU时间片用完,这就是时间片轮转调度。
目前,大多数嵌入式操作系统对不同优先级的任务采用基于优先级的抢占式调度法,对相同优先级的任务则采用时间片轮转调度法。
(4)硬实时和软实时
有些嵌入式系统对时间的要求较高,称之为实时系统。有两种类型的实时系统:硬实时系统和软实时系统。软实时系统并不要求限定某一任务必须在一定的时间内完成,只要求各任务运行得越快越好;硬实时系统对系统响应时间有严格要求,一旦系统响应时间不能满足,就可能会引起系统崩溃或致命的错误,一般在工业控制中应用较多。
(5)内存管理
针对有内存管理单元(MMU)的处理器设计的一些桌面操作系统,如Windows、Linux,使用了虚拟存储器的概念。虚拟内存地址被送到MMU。在这里,虚拟地址被映射为物理地址,实际存储器被分割为相同大小的页面,采用分页的方式载入进程。一个程序在运行之前,没有必要全部装入内存,而是仅将那些当前要运行的部分页面装入内存运行。 大多数嵌入式系统针对没有MMU的处理器设计,不能使用处理器的虚拟内存管理技术,采用的是实存储器管理策略。因而对于内存的访问是直接的,它对地址的访问不需要经过MMU,而是直接送到地址线上输出,所有程序中访问的地址都是实际的物理地址;而且,大多数嵌入式操作系统对内存空间没有保护,各个进程实际上共享一个运行空间。一个进程在执行前,系统必须为它分配足够的连续地址空间,然后全部载入主存储器的连续空间。
由此可见,嵌入式系统的开发人员不得不参与系统的内存管理。从编译内核开始,开发人员必须告诉系统这块开发板到底拥有多少内存;在开发应用程序时,必须考虑内存的分配情况并关注应用程序需要运行空间的大小。另外,由于采用实存储器管理策略,用户程序同内核以及其它用户程序在一个地址空间,程序开发时要保证不侵犯其它程序的地址空间,以使得程序不至于破坏系统的正常工作,或导致其它程序的运行异常;因而,嵌入式系统的开发人员对软件中的一些内存操作要格外小心。
(6)内核加载方式
嵌入式操作系统内核可以在Flash上直接运行,也可以加载到内存中运行。Flash的运行方式,是把内核的可执行映像烧写到Flash上,系统启动时从Flash的某个地址开始执行。这种方法实际上是很多嵌入式系统所采用的方法。内核加载方式是把内核的压缩文件存放在Flash上,系统启动时读取压缩文件在内存里解压,然后开始执行。这种方式相对复杂一些,但是运行速度可能更快,因为RAM的存取速率要比Flash高。
由于嵌入式系统的内存管理机制,嵌入式操作系统对用户程序采用静态链接的形式。在嵌入式系统中,应用程序和操作系统内核代码编译、链接生成一个二进制影像文件来运行。
2 嵌入式系统开发相关技术
相对于在Windows环境下的开发应用程序,嵌入式系统开发有着很多的不同。不同的硬件平台和操作系统带来了许多附加的开发复杂性。 2.1 嵌入式开发过程
在嵌入式开发过程中有宿主机和目标机的角色之分:宿主机是执行编译、链接、定址过程的计算机;目标机指运行嵌入式软件的硬件平台。首先须把应用程序转换成可以在目标机上运行的二进制代码。这一过程包含三个步骤:编译、链接、定址。编译过程由交叉编译器实现。所谓交叉编译器就是运行在一个计算机平台上并为另一个平台产生代码的编译器。常用的交叉编译器有GNU C/C++(gcc)。编译过程产生的所有目标文件被链接成一个目标文件,称为链接过程。定址过程会把物理存储器地址指定给目标文件的每个相对偏移处。该过程生成的文件就是可以在嵌入式平台上执行的二进制文件。 嵌入式开发过程中另一个重要的步骤是调试目标机上的应用程序。嵌入式调试采用交叉调试器,一般采用宿主机-目标机的调试方式,它们之间由串行口线或以太网或BDM线相连。交叉调试有任务级、源码级和汇编级的调试,调试时需将宿主机上的应用程序和操作系统内核下载到目标机的RAM中或直接烧录到目标机的ROM中。目标监控器是调试器对目标机上运行的应用程序进行控制的代理(Debugger Agent),事先被固化在目标机的Flash、ROM中,在目标机上电后自动启动,并等待宿主机方调试器发来的命令,配合调试器完成应用程序的下载、运行和基本的调试功能,将调试信息返回给宿主机。 2.2 向嵌入式平台移植软件
大部分嵌入式开发人员选用的软件开发模式是先在PC机上编写软件,再进行软件的移植工作。在PC机上编写软件时,要注意软件的可移植性,选用具有较高移植性的编程语言(如C语言),尽量少调用操作系统函数,注意屏蔽不同硬件平台带来的字节顺序、字节对齐等问题。以下是我们在移植协议栈过程中的一些体会。
2.2.1 字节顺序
字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的。因而对int、uint16、uint32等多于1字节类型的数据,在这些嵌入式平台上应该变换其存储顺序。通常我们认为,在空中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其它平台产品的互通,在程序中发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字节序转换为主机字节序。
2.2.2 字节对齐
有的嵌入式处理器的寻址方式决定了在内存中占2字节的int16、uint16等类型数据只能存放在偶数内存地址处,占4字节的int32 、uint32 等类型数据只能存放在4的整数倍的内存地址处;占8字节的类型数据只能存放在8的整数倍的内存地址处;而在内存中只占1字节的类型数据可以存放在任意地址处。由于这些限制,在这些平台上编程时有很大的不同。首先,结构体成员之间会有空洞,比如这样一个结构:
typedef struct test{
char a;
uint16 b;
}TEST
结构TEST在单字节对齐的平台上占内存三个字节,而在以上所述的嵌入式平台上有可能占三个或四个字节,视成员a的存储地址而定。当a存储地址为偶数时,该结构占四个字节,在a与b之间存在一个字节的空洞。对于通信双方都是对结构成员操作的,这种情况不会出错,但如果有一方是逐字节读取内容的(通信协议大都如此),就会错误地读到其它字节的内容。其次,若对内存中数据以强制类型转换的方式读取,字节对齐的不同会引起数据读取的错误。因为假如指针指在基数内存地址处,我们想取得占内存两个字节的数据存放在uint16型的变量中,强制类型转换的结果是取得了该指针所指地址与前一地址处的数据,并没有按照我们的愿望取该指针所指地址与后一地址处的数据,这样就导致了数据读取的错误。 解决字节对齐有许多方法,比如可以在GCC的项目管理文件MakeFile中增加编译选项--pack-struct;但这种方法只能去除结构中的空洞,并不能解决强制类型转换引起的错误。为了增强软件的可移植性以及和同类其它平台产品的互通性,我们在收数据包处增加了拆包的函数,发数据包处增加了组包的函数。这两个函数解决了字节序的问题,也解决了字节对齐的问题。即组包时根据参数中的格式字符串将内存中的不同数据类型的某段数据放在指定地址处,组成包发给下层;拆包时,根据参数中的格式字符串将收到的内存中的数据存放在不同类型的变量或结构成员中。在函数中针对不同的数据类型作不同的处理。 2.2.3 位 段
由于位段的空间分配方向因硬件平台的不同而不同,对X86平台,位段是从右向左分配的;而一些嵌入式平台,位段是从左向右分配的。分配顺序的不同导致了数据存取的错误。解决这一问题的一种方法是采用条件编译的方式,针对不同的平台定义顺序不同的位段;也可以在前面所述的两个函数中加上对位段的处理。
2.2.4 代码优化
嵌入式系统对应用软件的质量要求更高,因而在嵌入式开发中尤其须注意对代码进行优化,尽可能地提高代码的效率,减少代码的大小。虽然现代C和C++编译器都提供了一定程度的代码优化,但大部分由编译器执行的优化技术仅涉及执行速度和代码大小的平衡,不可能使程序既快又小,因而必须在编写嵌入式软件时采取必要的措施。
(1)提高代码的效率
①switch-case 语句。在程序中经常会使用switch-case语句,每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就浪费了处理器时间。为了提高速度,可以把具体的情况按照它们发生的相对频率排序。即把最可能发生的情况放在第一,最不可能发生的情况放在最后,这样会减少平均的代码执行时间。
② 全局变量。使用全局变量比向函数传递参数更加有效率,这样做去除了函数调用前参数入栈和函数完成后参数出栈的需要。当然,使用全局变量会对程序有一些负作用。
(2)减小代码的大小
嵌入式系统编程应避免使用标准库例程,因为很多大的库例程设法处理所有可能的情况,所以占用了庞大的内存空间,因而应尽可能地减少使用标准库例程。
(3)避免内存泄漏
用户内存空间(堆)为RAM中全局数据和任务堆栈空间都分配后的剩余空间,为了使程序能有足够的内存运行,必须在申请的内存不用后及时地将其释放,以确保再次申请时能有空间。如果程序中存在内存泄漏(即申请内存后没有及时释放)的情况,程序最终会因为没有足够的内存空间而无法运行。 3 嵌入式系统的广泛应用
嵌入式系统的应用前景是非常广泛的,人们将会无时无处不接触到嵌入式产品,从家里的洗衣机、电冰箱,到作为交通工具的自行车、小汽车,到办公室里的远程会议系统等等。特别是以蓝牙为代表的小范围无线接入协议的出现,使嵌入式无线电的概念悄然兴起。当嵌入式的无线电芯片的价格可被接受时,它的应用可能会无所不在。在家中、办公室、公共场所,人们可能会使用数十片甚至更多这样的嵌入式无线电芯片,将一些电子信息设备甚至电气设备构成无线网络;在车上、旅途中,人们利用这样的嵌入式无线电芯片可以实现远程办公、远程遥控,真正实现把网络随身携带。下面介绍几种具体的应用。
(1)嵌入式移动数据库
所谓的移动数据库是支持移动计算的数据库,有两层含义:① 用户在移动的过程中可以联机访问数据库资源。② 用户可以带着数据库移动。典型的应用场合有在开着的救护车上查询最近的医院。该系统由前台移动终端、后台同步服务器组成,移动终端上有嵌入式实时操作系统和嵌入式数据库。中国人民大学正在开发该系统,他们和Hopen公司合作,开发了前台移动终端"小精灵"。
(2)嵌入式系统在智能家居网络中的应用
智能家居网络(E-Home)指在一个家居中建立一个通信网络,为家庭信息提供必要的通路;在家庭网络操作系统的控制下,通过相应的硬件和执行机构,实现对所有家庭网络上家电和设备的控制和监测。其网络结构的组成必然有家庭网关。家庭网关主要实现控制网络和信息网络的信号综合并与外界接口,以便作远程控制和信息交换。不论是网关还是各家电上的控制模块,都需有嵌入式操作系统。这些操作系统必须具有内嵌式、实时性好、多用户的特点。南京东大移动互联技术有限公司研制的智能多媒体家庭网关,就是以嵌入式Linux作为该嵌入式设备的操作系统,设备之间的相互通信遵从蓝牙通信协议,可以支持多个设备同时接入到固定电话网、国际互联网等其它外部网络。
(3)嵌入式语音芯片
嵌入式语音芯片基于嵌入式操作系统,采用语音识别和语音合成、语音学层次结构体系和文本处理模型等技术;可以应用在手持设备、智能家电等多个领域,赋予这些设备人性化的交互方式和便利的使用方法;也可应用于玩具中,实现声控玩具、仿真宠物、与人对话的玩具;也能应用于车载通信设备实现人机交流。该芯片应用在移动通信设备中,比如,手机上短消息来时,我们不必费力地去看,而是可以听到声音。 (4)基于小范围无线通信协议的嵌入式产品
以蓝牙为代表的小范围无线接入协议与嵌入式系统的结合,必将推动嵌入式系统的广泛应用。近来,基于这些协议的嵌入式产品层出不穷,包括各种电话系统、无线公文包、各类数字电子设备以及在电子商务中的应用。这些产品以其微型化和低成本的特点为它们在家庭和办公室自动化、电子商务、工业控制、智能化建筑物和各种特殊场合的应用开辟了广阔的前景。
东南大学移动通信国家重点实验室以及依托实验室建立的南京东大移动互联技术有限公司,从1998年开始跟踪蓝牙技术,在香港特区政府创新科技基金、江苏省"十五"重大科技攻关以及国家"十五"科技攻关的资助下,先后设计和研制了多种基于蓝牙技术的嵌入式产品。其中包括符合Bluetooth V1.1标准的嵌入式PSTN网关和语音终端。它们基于蓝牙"三合一电话"应用模型,选用了中国科学院凯思昊鹏软件技术工程有限公司提供的Hopen OS作为嵌入式开发的软件平台,选用华邦的W90221作为硬件平台。语音终端能通过PSTN网关以无线的方式接入到PSTN网络中,实现和PSTN网用户的互通。还有符合Bluetooth V1.1标准的嵌入式局域网接入点,它基于蓝?quot;局域网接入"应用模型,选用嵌入式Linux操作系统作为软件平台,选用Motorola公司的CodeFire 5272作为硬件平台。通过该接入点,终端用户可以自由地接入到Internet,可以同时支持多个终端用户连接到Internet。其它一些嵌入式产品包括智能多媒体家庭网关、远程抄表系统、信息家电等等。
结 语
以上重点介绍了嵌入式系统的特点、嵌入式产品的开发和应用。我们在开发过程中体会到:嵌入式系统开发和以前从事的开发工作实质上并无区别,唯一改变的是每个硬件平台都是独特的,这一个不同点导致了许多附加的开发复杂性,因而,在嵌入式开发过程中要格外注意软件创建过程;而且,在开发嵌入式产品之前要对选用的嵌入式硬件平台有较多的了解,具备相应的硬件知识,和硬件工程师密切配合;在选用嵌入式操作系统和硬件平台时要根据所要开发的应用的需要以及成本等方面的考虑选择合适的系统和平台。
在科技快速发展的今天,嵌入式产品将会越来越多地被广泛应用。我们相信,只要遵循嵌入式产品的开发规律,适应市场的需求,就一定能开发出越来越多的嵌入式产品。