嵌入式系统应用程序移植的研究
周正, 童维勤
(上海大学计算机学院 上海市延长路149号 200072)
摘 要:随着嵌入式系统的大量使用,对各类应用程序的需求也日益增长,为了避免应用程序的重复开发,往往需要将基于某一嵌入式操作系统平台的应用程序移植到另一操作系统平台之上。本文以当前比较流行的两个嵌入式操作系统VxWorks和uCLinux为例,通过分析两者之间的差异,对应用程序在这两个系统间的移植进行了探讨。
关键词:嵌入式系统; 移植; VxWorks; uCLinux 中图法分类号:TP316 文献标识码:A
The study of porting the embedded application
ZHOU-Zheng TONG-WeiQin
(Yanchang road 149 Shanghai China 200072)
Abstract: the need of the application programs grow increasingly with a great deal of using of the embedded system. The porting of the application between different embedded operation systems is a normal method that people always use to avoid the repeating development of the application. The paper chiefly studied the porting of application between the two most popular embedded operation systems-VxWorks and uClinux by analyzing the difference between them.
Key words: embedded system; porting; VxWorks; uCLinux
随着互连网的迅速普及与应用,计算机、通讯与消费电子一体化趋势日趋明显,这将进一步改善我们的工作与生活。在各类数字化产品中,嵌入式系统是重要的组成部分。嵌入式系统并不是一个新生的事物,很早便应用于军事、自动化控制以及消费电子产品领域。嵌入式系统的广泛应用前景和发展潜力使其成为21世纪的应用热点之一。
早期的嵌入式系统以控制为主,功能比较单一,一般没有明显的被称为操作系统的软件的支持。随着计算机技术的迅猛发展,嵌入式应用系统的功能日渐复杂,为提高硬件资源使用率和程序设计效率,人们在开发一些复杂的嵌入式系统时引入了嵌入式操作系统。从20世纪80年代开始,出现了各种各样的商用及开源操作系统,其中较为著名的有VxWorks、pSOS、PalmOS、Windows CE和Linux等。操作系统的引入方便了应用程序的开发,提高了开发效率,增强了系统的可靠性以及资源利用率。
市场上可供选择的嵌入式操作系统种类繁多,各具特色,在面向同一应用领域的不同嵌入式系统中,使用的操作系统往往也不尽相同,而针对该领域所设计的应用程序所实现的逻辑功能往往都是一样的,比如:我们为一款PDA开发了基于Linux的电子邮件收发软件,而另一款运行Win CE的PDA也需要一个电子邮件收发软件,显然,两款PDA上的电子邮件收发软件所实现的逻辑功能都是一样的,但运行的操作系统却不一样。
为避免应用程序的重复开发,往往需要将嵌入式系统应用程序跨操作系统平台进行移植。在上例中,为了避免为运行有Win CE的PDA重新开发一套电子邮件收发软件,可以将已在Linux平台上运行的电子邮件收发软件移植到Win CE平台上。
本文以下部分将以当前两个比较流行的嵌入式操作系统VxWorks和uCLinux为例,对嵌入式系统应用程序的移植进行探讨。
*上海市科委科技攻关计划基金,编号 04DZ15011
http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛
1 VxWorks与uCLinux简介
VxWorks 是美国Wind River System 公司推出的一个高性能、可裁减的嵌入式实时操作系统。它以其良好的可靠性和卓越的实时性被广泛应用在通信、军事、航空航天等高精尖
技术及实时性要求极高的领域中。它提供了良好的可配置能力,可配置的组件超过80个,允许按照不同的应用需求进行定制。VxWorks支持多种CPU,同时还支持RISC、DSP等技术,具备强大的网络功能。
uCLinux是专门针对嵌入式系统开发的一款开源操作系统,在传统Linux的基础上进行了一些精简与修改,具备了传统Linux的稳定、网络功能强大等特色。并且体积小巧,成本低廉,能根据具体应用进行配置。在硬件支持方面可以支持不带MMU的CPU。
由于VxWorks是一款基于优先级、任务可抢占的实时操作系统;而uCLinux内核在实时方面有所增强,也支持基于优先级的任务调度,但它不支持任务抢占,因此它仍然不是严格意义上的实时操作系统。鉴于两者之间在实时性方面的差异,本文所考虑的应用程序在实时性方面均没有严格的要求。如果某一类应用对实时性有严格要求,那么从一个实时系统向一个非实时系统移植往往会对其响应时间有所影响。 2 嵌入式应用软件的移植
由于每个嵌入式操作系统在核心运行机制、各功能的实现方式、用户接口等方面均存在一定差异,这些差异决定了不同的平台都具有其各自的特性、开发环境及程序运行环境。因此,跨操作系统平台的应用程序移植具有一定的困难与复杂性。
使用操作系统的嵌入式系统通过操作系统来管理系统各类资源,设计人员用高级语言(如c语言)进行应用程序开发时通过调用操作系统提供的接口函数来对各类设备进行操作。通过使用这些接口可以方便的对系统的各类资源进行控制,因此用户接口几乎是上层应用程序必不可少的重要组成部分。由于各类操作系统都有各自特点,提供的用户接口也各不相同,因此基于某类操作系统运行的应用程序往往只能在这类操作系统上运行,在其他操作系统会因为调用的接口不一致或其他方面因素而无法运行。
VxWorks和uCLinux的一些接口兼容POSIX标准,这在一定程度上降低了应用程序移植的难度,但VxWorks和uCLinux仍有大量专有API。这些系统专有的API在实现机制和调用界面等方面都是不一致的。
因此,解决不同系统间系统调用接口的不一致问题是进行应用程序移植的关键任务。当前,解决嵌入式系统应用程序跨操作系统平台移植时的接口不一致问题的方法主要有:接口重构与接口模拟。 2. 1接口重构
接口重构的主要任务是对基于某一系统开发的应用程序的源码进行相应修改,将源码中出现的系统调用接口更改成要移植的目标系统的接口。
对于程序源码中较简单的接口,只需将其修改成为目标系统中与其功能一致的接口即可。而对于原系统平台中一些比较复杂的接口,由于其运行机制等与目标系统不同,无法进行直接的替换,往往需要针对目标系统接口的运行机制添加额外的代码,并在目标系统中对多个系统调用接口进行整合或封装。
接口重构技术是目前嵌入式系统应用程序移植所采用的主要技术,由于在移植过程中要对代码进行大幅度修改,因此要做大量工作,并且在代码修改的过程中甚至会出现程序逻辑结构被破坏、修改过程中引入错误等问题,影响了程序的正确性及可靠性。而且,利用接口重构技术仅针对某一个具体应用程序进行移植,如果要对多个应用程序进行移植,则不得不对多个应用程序的源代码进行修改,由于很多常用接口经常反复出现在多个程序中,因此,移植过程中进行了许多重复劳动,降低了效率。
鉴于接口重构技术的这些弊端,我们在进行移植工作时经常采用另一种技术——接口模拟技术。下面对这种移植技术进行介绍。
http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛
2.2 接口模拟
接口重构技术对于仅拥有简单系统调用接口的嵌入式应用程序而言,能够较为方便彻底的实现跨操作系统平台的移植。但对于包含复杂系统调用接口的程序而言,重构过程中要做大量复杂重复的工作。接口模拟技术能够很好的解决采用接口重构技术所遇到的问题。
所谓接口模拟,是指在目标系统平台上利用目标系统的API来模拟原系统中的API。即在目标平台上重新设计一套接口函数,函数的格式与原系统API的格式一致,通过利用目标平台的API来实现相应函数的功能。也就是说,接口模拟技术就是基于目标系统平台的API写了一个原系统平台API的模拟层。如图1所示:
原系统程序 通过调用模拟层API重现其功能原系统平台API模拟层 通过调用目标平台的API实现模拟目标系统平台API 目标系统平台 图1 这样,在宿主机上创建一个函数库,将这套重新设计的用来模拟原系统API的函数包含到里面。移植时将应用程序源代码与这个函数库连接到一起,用与目标嵌入式系统CPU相对应的编译器重新编译一遍即可。采用接口模拟技术有着诸多优点:
1、不用对原系统应用程序的源代码进行修改或进行少量修改,确保了在原有程序中不会引入新的错误,程序的原有逻辑结构与功能不会受到影响。
2、避免了在移植过程中进行过多重复劳动。移植时只需在宿主机上将应用程序的源代码与模拟接口库连接进行交叉编译即可生成可以在目标系统上运行的应用程序。这样,在移植多个程序时只需重复上述简单步骤即可,或编写脚本文件来自动实现上述步骤,免去了对每个程序源代码进行更改的烦琐工作。
3、成果易于共享。既可以将自己编写的共享库提供给别人使用,也可以利用别人编写的共享库进行程序的移植。
将应用程序在VxWorks与uCLinux这两个系统平台间进行移植时,由于VxWorks是一个实时操作系统,一些接口的设计是面向实时应用的,实现机制往往也要考虑实时性;而uCLinux并不是一个实时系统,因此两者之间许多接口的差异比较大。在移植过程中利用目标系统API创建接口模拟函数时,如果目标系统API所具有的一些特性原系统API没有,则要隐藏这些特性;对于目标系统API所不具有,而被模拟系统接口所具有的特性,需要将这些特性体现出来。 3 应用实例
下面给出一个简单的应用实例来说明如何利用接口模拟技术将一个运行在VxWorks上的应用程序移植到uCLinux平台。两个操作系统运行的硬件环境都是三星公司的ARM9处理器S3C2410。
该应用程序实现的主要功能是创建两个任务,每个任务各显示一条字符串。源程序如下: #include \"time.h\" void print_task(); void usrAppInit (void) { /*VxWorks中用户程序的入口函数*/
char* message1=\"hello \"; char* message2 =\"world\";
http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛
struct timespec* delay;
delay = (struct timespec *) malloc (sizeof(struct timespec)); delay->tv_sec=1; delay->tv_nsec=0; /*设置定时时间为1秒*/ taskSpawn ( \"task1\90, 0X80, 20000,print_task,message1); /*创建任务1*/
nanosleep(delay,0); /*延时1秒后显示另一字符串*/
taskSpawn (\"task2\创建任务2*/ } void print_task(const char *msg){ /*用来显示字符串的任务函数*/ printf(\"%s\msg); }
程序的运行结果为:“hello world”
这段程序中用到的系统调用有taskSpawn()与nanosleep(),taskSpawn()是VxWorks专有API,需要进行模拟,而nanosleep()是符合POSIX标准的API,由于uCLinux支持POSIX标准,因此该函数无需进行模拟。uCLinux下利用uCLinux系统调用简要实现taskSpawn()函数功能的程序代码如下:
#include char * name;/* 任务的名称*/ int priority,;/* 实时任务的优先级,1为最高优先级 */ int options;/*创建选项,这里不做处理*/ int stackSize;/* 任务堆栈的大小 必须大于16384字节*/ void * (*entryPt)();/* 任务的函数入口 */ void* arg;/*任务入口函数的参数 */ ) { struct sched_param tSchParam; /*定义线程调度属性参数*/ pthread_attr_t tThreadAttr; /*定义线程属性参数*/ pthread_t thread_id; /*定义任务id*/ pthread_attr_init(&tThreadAttr); /*初始化线程属性*/ pthread_attr_setstacksize(&tThreadAttr, stackSize); /*设置堆栈的大小*/ pthread_create(&thread_id, &tThreadAttr,entryPt, arg1); /*创建新任务*/ tSchParam.sched_priority = 100 - priority; /* 设置任务的优先级*/ pthread_setschedparam(thread_id, SCHED_FIFO, &tSchParam); return (int)thread_id; /*返回任务id*/ } 在uCLinux平台上对该VxWorks应用程序进行模拟时共用到了pthread_create()、pthread_attr_init()、pthread_attr_setstacksize()、pthread_setschedparam()这四个系统调用。在VxWorks的系统调用taskSpawn()中的name参数一般仅用来在给出提示信息时显示出任务的名字,这里没有对其进行处理;options参数在VxWorks系统里用来指定所创建任务的执行方式,共有4个选项: VX_FP_TASK 使用浮点协处理器 VX_NO_STACK_FILL 堆栈不用值0xee填充 VX_PRIVATE_ENV 在私有环境下执行任务 VX_UNBREAKABLE 禁止在任务中设置断点 这里也未对该参数进行处理。 将编制好的模拟函数用针对相应嵌入式处理器的编译器交叉编译成一个库文件,这样,在移植VxWorks程序时,使用同样的编译器,并将该库文件所在位置告诉编译器,这样编译器在编译源程序时会自动连接到动态库,最终生成可执行代码。 http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 4 结语 本文所介绍的接口重构技术是目前进行嵌入式系统应用程序移植最常用的方法,它直接对应用程序源码中的调用接口进行修改,从而达到与目标系统的接口对应,除此之外还要对源代码的其他部分进行修改,最终通过重新编译实现在目标平台上的运行。随着嵌入式系统功能日渐增多,应用程序越来越复杂,采用这种方法的会使工作量增大,错误增多,而且无法复用。 本文作者的创新观点:利用接口模拟技术进行嵌入式应用程序的移植,这样在不更改应用程序源码的情况下实现了对应用程序调用接口的模拟,所编制的模拟接口可以通过共享库的形式存在,易于复用,在进行多个应用程序移植时能有效降低工作量,提高效率,是一种方便、高效的方法。解决了传统方法的一些弊端。 参考文献 1 金西,黄汪.Linux操作系统是嵌入式系统新的选择.微计算机信息,第16卷第6期2000:1-3. 2 林涛,孙鹤旭,云立军,梁涛.Linux在嵌入式系统中的实现.微计算机信息, 第21卷第7期 2005:27-28. 3 孔祥营. 嵌入式实时操作系统及其开发环境Tonado. 北京:中国电力出版社,2002 4 周启平. VxWorks程序员速查手册. 北京:机械工业出版社,2005 作者简介 周正,男,1982年1月4日生,汉族,硕士,研究方向为嵌入式系统。 童维勤,男,1964年12月22日生,汉族,教授,博士生导师,主要研究方向为并行程序设计方法和编译技术、嵌入式系统 Zhou-Zheng, male, born in January 4,1982, the Han nationality,master,the main research subject is the embedded system. Tong-WeiQin,male,born in december 22,1964,the Han nationality,Professor,the mentor of doctor,the main research subject is parallel program design, compiler technique and embedded system. 因篇幅问题不能全部显示,请点此查看更多更全内容