陈荣观
摘要:VxWorks以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。Linux完全开源,全世界拥有几十万的开源项目,目前主流的Android及嵌入式设备都采用Linux操作系统。该文着重介绍将基于VxWorks开发的应用程序移植到Linux的技术实现。
关键词:Linux;Vxworks;RTOS;程序迁移;嵌入式
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2016)09-0087-03
1概述
VxWorks是美国Wind River System公司(以下简称风河公司,即WRS公司)于十九世纪八十年代设计开发的一种嵌入式实时操作系统(RTOS)。良好的持续发展能力、高性能的内核以及友好的组件化用户开发环境,在嵌入式实时操作系统领域占据一席之地。它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。在美国的 F-16、FA-18战斗机、B-2 隐形轰炸机和爱国者导弹上,甚至连1997年4月在火星表面登陆的火星探测器、2008年5月登陆的凤凰号,和2012年8月登陆的好奇号也都使用到了VxWorks。
Linux操作系统经过二十几年的发展,其拥有几十万的开发人员,成千上万的开源项目,成为了开发人员的首选。在移动领域借助Android与IOS平分天下。在嵌入式领域,随着CPU主频的发展,克服了Linux分时操作系统的实时缺陷,其精度已经完成可以满足大部分实时领域的要求,特别在民用领域。目前除了在工业控制,航天,军用领域保持优势以外,VxWorks的优势荡然无存。
目前开发人员碰到使用新的硬件方案,厂家基本上不提供VxWorks的Bsp,只支持Linux。这个给开发人员增加了很大的开发成本,所有的程序跟模块都要重新设计,以适应新的系统,增加了开发周期。本文设计一种方案,可以很方便地将VxWorks的应用程序搬迁到Linux上,为厂家缩短开发周期,减少程序搬迁风险,大大降低了开发成本。本文先介绍VxWorks的技术原理,然后分析技术实现细节,最后拿一个应用程序作为例子。
2 VxWorks系统原理
VxWorks操作系统以实时著称,系统代码组件化比较好,系统精简,产品的IMAGE可以做的非常小。VxWorks属于共享内存的操作系统,没有进程的概念,按照任务进行调度,每个任务是分配了堆栈,可以访问系统的所有内存空间,比较高效,但是也比较危险,很容易就会发生系统崩溃的情况。但是也就是因为这个特性,因此基于VxWorks开发的产品一般是单个应用产品,这个打包完可以以一个进程体现在Linux里面。
VxWorks系统主要如下几个组件,一般的应用程序也就用到如下几个模块:任务调度负责任务优先级,任务创建,任务删除等功能。任务通讯主要涉及队列管理,管道管理等。IO管理就是通用外设的输入输出管理。文件管理包含文件或者链接创建,修改,删除,检索等等。内存管理包含内存申请及内存释放。定时器管理就是定时器创建,定时器删除。网络通信包含套接字创建,udp/tcp通信,套接字删除,及配置管理。同步就是任务同步。互斥就是任务互斥,保护关键资源。
在VxWorks操作系统的代码架构里面,一般写一个应用程序只需要涉及上面几个系统组件,由于VxWorks操作系统组件化非常好,这几个组件的耦合度非常低,每个组件对外提供都是单独的头文件,比如任务调度,其头文件为taskLib.h,任务通讯如果用的队列,那其头文件就是msgQLib.h,如果是定时器管理,那其头文件就是timerLib.h,因此也让程序移植提供了很大的便利性。有很多人认为,VxWorks跟Linux操作性的系统头文件差异化太大,因此移植难度成倍速增加,其实不然,就是由于VxWorks的高度组件化,让程序移植提供了很大的便利性。
3 技术实现
我们假设现在要移植一个简单的聊天程序到Linux,那么其应该包含网络通讯组件(udp通讯),任务调度组件(任务创建),任务通讯(队列报文排序管理),内存管理(内存申请),定时器模块(报文超时重发),任务互斥/同步(并发多人聊天)等基础组件,虽然功能简单,但是基本上也包含了常用的功能,我们就以这个为例来谈谈技术实现。正常这个程序在Linux上是无法编译的,因为里面引用了大量的VxWorks的头文件,而这些在Linux上是没有的。
正常这个应用程序要包含的系统头文件如下:
VxWorks.h作为VxWorks的系统头文件,里面主要定义了一些常量,比如#define OK 0等,因此我们只要将VxWorks.h随程序发布到Linux系统,做一下稍微修改即可,不用特意修改,甚至可以删除的只剩下我们程序有用到的常量,如果没有用,完全没有必要假如,避免编译出错。
我们着重讲解,几个重要模块如何在Linux系统上实现,以保证基于VxWorks系统原型写的程序能够无缝的移植到Linux上。其实我们只要把上述的几个头文件在Linux上实现一遍即可。
3.1 任务与进程、线程对比
VxWorks的任务是VxWorks的最小运行单元,每个任务之间是共享内存,可以互相访问,这个有点类似Linux的线程的概念,而几个任务合起来的嵌入式产品就等同于一个进程。
因此在具体实现上,我们只要针对taskLib中的关键函数进行Linux实现即可实现正常的任务调度。具体的函数对应关系如下表格。
3.2 消息队列实现
VxWorks的常用消息队列进行任务间通讯,在传输较小的数据块时,效率较高,并且允许消息进行排队,Linux没有很好的消息队列实现方式,对于线程间的异步通讯一般都是开发者自己实现。对于Linux的线程间通讯,我们采用管道来实现,管道既可以用用于进程间通讯,也可以用于线程间通讯。管道是一种半双工的通信机制,也就是说,它只能一端用来读,另外一端用来写。管道通信遵循先进先出的原理,并且数据只能被读取一次,当此段数据被读取后,马上会从数据中消失,这一点很重要。Linux上,创建管道使用pipe函数,当它执行后,会产生两个文件描述符,分别为读端和写端,因此可以采用标准的IO进行操作。
3.3 定时器实现
VxWorks操作系统的优势就是在定时器上,VxWorks定时器具有完美的实时特性,定时器的优先级低于硬件驱动,但是高于任何的应用优先级。Linux由于是先天的分片操作系统,并且内核跟应用有隔离,应用态的定时器其实是不准的,但是就如开题说的,目前的CPU由于主频很高,完全实时已经没有太大必要,基本上目前Linux的分时特性可以满足大部分的应用领域,为了实现定时器的准度,我们在Linux系统上采用采用select进行时间定时,如果有时间产生,则进行纠正。详细逻辑参加图4,定时精度可以通过参数传入。
3.4 任务间同步,互斥实现
VxWorks提供的信号量经过了高度优化,在所有任务间通信机制中,速度最快。二进制信号量(semLib)可以实现任务同步,互斥信号量(semLib)可以实现任务互斥。在Linux底下,能够实现同步跟互斥的方法非常多,我们选择sem_t来实现二进制信号量,选择pthread_mutex_t来实现互斥信号量。对应关系如表4。
3.5 其他实现
VxWorks在socket方面的管理与Linux基本上一模一样,指示引用的头文件不一样,只要协议sockLib.c引用linux的头文件即可。在内存管理方面完全一样,不用特殊处理。
4 结束语
通过上述的关键模块替换方式,基本上可以满足VxWorks的应用程序到Linux的搬迁,程序主体不用做任何改动。VxWorks操作系统虽然应用领域越来越少,但是其组件化的设计理念,使得在其上面设计的应用程序调理清晰,结构简单。笔者已经尝试了将融合通信领域的嵌入式软件完成的搬迁到Linux,Window,Android等主流应用程序上,所要做的就是针对不同的应用平台写几个关键模块的操作系统适配层即可。
参考文献:
[1] Comer D E, Stevens D L. Internetworking with TCP/IP, Vol. III: Client-Server Programming and Applications, Linux/Posix Sockets Version[M]. Pearson, 2000.
[2] 宋敬彬.Linux网络编程[M].2版.北京:清华大学出版社,2014.
[3] 张保山,俞烈彬.VxWorks驱动及分布式编程[M].北京:中国电力出版社,2007.
[4] 曹桂平.VxWorks设备驱动开发详解[M].北京:电子工业出版社,2011.