基于QNX的嵌入式操控训练系统软件设计
2014-06-30王立伟胡大斌肖剑波
王立伟 胡大斌 肖剑波
摘 要: QNX操作系统具有可靠性高、实时性强的特点和强大的图形界面功能,基于其开发的水下航行器嵌入式操控训练系统,解决了系统的实时性需求,还能方便地开发出友好的人机界面。简要介绍了QNX操作系统的特点和映像文件配置的一般方法,基于PhAB开发了嵌入式操控训练系统的操控界面,根据系统的模块划分对主程序进行了设计,系统程序运行稳定,满足训练要求,对其他嵌入式训练系统软件设计具有一定的借鉴意义。
关键词: QNX; 图形界面; 建模; 嵌入式训练系统
中图分类号: TN964?34 文献标识码: A 文章编号: 1004?373X(2014)12?0015?04
Abstract: QNX, an operating system with strong development function of graphic interface, has the characteristics of high real?time performance and reliability. The embedded control training system for underwater vehicle developed on the basis of QNX can meet real?time requirement of the system and can develop friendly man?machine interface conveniently. The characteristics of QNX and the general ways to configure mapping files are briefly introduced. The control interface of the embedded control training system based on PhAB was developed. The main program was designed according to the sort of modules. The embedded control training system can fulfill the requirements of training, and runs steadily, which can be used as a reference to the software design of other embedded training systems.
Keywords: QNX; GUI; modeling; embedded training system
0 引 言
操纵控制系统是水下航行器的指挥中枢,用于控制操纵设备来改变或保持运动速度、姿态和深度,其可靠性和实时性决定了水下航行的安全。嵌入式操控训练系统在原有操控系统的基础上加装了训练模块,集操纵控制和训练功能于一身,提高了训练效率,降低了训练成本,但也对系统性能提出了更高的要求。QNX操作系统作为一款主流的嵌入式实时操作系统,可靠性高,实时性强,图形界面开发功能强大,基于其开发的水下航行器嵌入式操控训练系统即能满足实时性方面的要求,又具有友好的人机交互界面。
1 QNX概述
QNX是由加拿大QSSL公司开发的一款嵌入式实时操作系统,具有实时性强、多任务、分布式、可扩展的特点和强大的图形界面开发功能,广泛应用于军事、航空航天、医疗设备、车载系统、高端网络系统和自动化等领域[1]。独特的中断处理方式,快速的上下文切换和基于优先级驱动的抢占调度方式,保证了其强大的实时性能。QNX的内核仅执行四种最基本的功能,使得系统具有良好的可靠性,而高度的可裁剪性也让其在嵌入式开发方面具有得天独厚的优势。此外,QNX还具有良好的可移植性和自保护机制,符合POSIX标准,这些都使得其在嵌入式实时领域得到了越来越广泛的应用。
2 系统软件设计
2.1 QNX系统映像文件的配置
映像文件包括操作系统,可执行程序和任何与程序相关的数据文件,是嵌入式系统开发的基础,为系统软件设计提供了平台。根据系统的实际需求制作合适的操作系统映像文件,可以充分发挥嵌入式系统小巧的特点,在节省内存资源的同时也保证了系统的整体性能。具体说来就是根据自己所选择的CPU类型和应用程序所需要的操作系统模块支持来定制系统,在保证既定功能的基础上裁剪掉与实现功能无关的文件,实现系统的最小化。
在建立映像文件之前必须编辑生成一个QNX的buildfile文件,buildfile文件一般由bootstrap script(启动引导脚本)、startup script(启动脚本)、file list(文件列表)三部分组成[2]。启动引导脚本用于指明CPU的启动方式,配置与CPU相适应的微内核。对于x86及其兼容的嵌入式计算机,通常格式如下:
[virtual=x86,bios +compress] .bootstrap = {
startup?bios
PATH=/proc/boot:/bin LD_LIBRARY_PATH=/proc/boot:/lib:/dll procnto}
其中x86为处理器类型,对于其他类型的CPU可根据参考手册进行相应的替换;bios +compress指通过bios启动,并压缩镜像文件; “PATH=/proc/boot” 确定了PATH环境变量;“procnto” 是微内核和进程管理器。
启动脚本是在进程管理启动后一系列将要被执行命令的序列,用于在引导脚本执行完后运行驱动程序和用户程序,通常格式如下:
[+script] .script={
command line
}
文件列表是指系统程序和用户程序执行所必须的文件列表和一些共享库,通过[type=link]重新定位它们的位置。由于本文所设计的嵌入式操控训练系统以C语言为开发语言,所有的驱动至少需要一个标准C共享库:
[type=link] /usr /lib/ldqnx.so.2=/proc/boot/libc.so
libc.so #标准C共享库
完成buildfile文件的编译后,使用mkifs命令即可生成镜像文件.ifs。例如:mkifs ControlSystem.build ControlSystem.ifs。通过objdump命令,可以检查镜像文件是否包含了全部所需文件。然后将镜像文件嵌入到目标机中,运行后即可看到用户定制的嵌入式操作系统。
2.2 应用程序设计
2.2.1 模块化设计
嵌入式操控训练系统不仅要实现对水下航行器的操纵和训练等功能,还应能处理系统内部和外部的各种输入输出信号读写、计算和通信。根据系统的功能,将其分为以下模块:
(1) 系统控制模块:管理系统运行状态、数据通信等。
(2) 界面程序模块:显示深度、航向和纵倾的设定值;显示深度、航向、纵倾、横倾的当前值;显示方向舵、舯水平舵和艉升降舵当前的舵角值。
(3) 运动模型模块:模拟水下航行器的运动状态,根据六自由度方程解算出当前的状态参数值。
(4) 舵机模型模块:模拟舵机,输出舵角值。
(5) 航向、深度、纵倾控制模块:自动和遥控工况下航向、深度、纵倾的保持和改变。
(6) 工作模式转换模块:完成训练模式和操控模式的快速安全切换。
除上述模块外,还包括数据采集卡控制模块、接口控制模块和通信模块。通过采用模块化设计方法,降低了软件结构的复杂性,方便了软件设计,降低了开发难度。软件系统的模块结构如图1所示。
2.2.2 界面设计
QNX为用户提供了三种开发图形的方法,即GF(Graphics Framework),Adobe Flash,Photon microGUI[3]。利用GF进行图形界面开发具有小巧、高速的优点,能有效和最大限度地利用显示硬件,但缺少像Photon中的可直接使用的控件,而且也没有特别的编程工具,开发难度较大。利用Adobe Flash开发的图形界面不依赖于操作系统,仅需支持Flash就可以使用。用户通过FLASHDEVELOP软件编写的图形界面更加绚丽,但其在嵌入式设备上的性能还有待提高。
Photon microGUI采用了与QNX微内核相同的结构,图形窗口的构建是通过微内核和一组共操作的进程来实现的,使得窗口系统占用的空间少而可靠性高。Photon自带的PhAB开发工具采用所见即所得的开发模式,可以自动生成主要的C和C++代码来完成工程的用户界面,大大提高编程效率。本文采用PhAB开发工具进行界面设计。
PhAB提供了76个控件类,用户可以直接将需要的控件拖到绘图窗口,设定大小,在Resources窗口中设置各类属性,在Callbacks中选择回调函数的类型和设置函数名称,之后选择Build下的Genrate UI命令即可生成目标代码。
目标代码生成后,用户可以利用QNX Momentics IDE软件编写相应的初始化函数、回调函数和其他函数。本文所设计的界面需要实现对深度、航向和水下航行器运行状态等动态数据的实时显示,下面以界面中显示航向的动态码盘绘制为例介绍程序设计的一般方法。
动态码盘的绘制采用的是具有自动重绘功能的PtRaw控件,回调函数包括:
(1) 绘图函数:void course_draw( PtWidget_t *widget, PhTile_t *damage )。负责绘制柱形码盘。
(2) 定时器函数:int timer_refresh( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )。负责定时调用清除函数或发送事件,从而引发绘图函数根据新数据自动重绘。
绘图函数通过设置PtRaw控件的Pt_ARG_RAW_
DRAW_F资源进行定义。函数定义中的*widget是指向PtRaw控件的指针,指针为ABW_加上控件的变量名,*damage是指向碎片的指针,用于程序识别PtRaw控件画布中被销毁的部分。
绘制动态码盘就是要不断的调用绘图函数进行重绘,然而绘图函数不能被直接调用,只能通过销毁PtRaw控件画布的方式来达到重绘的目的。满足以下两个条件之一即可以销毁画布:
(1) PtRaw控件实现时;
(2) 覆盖在画布上的区域被移走或销毁。
前者可以用PtClearWidget()和PtReRealizeWidget()函数来实现。PtClearWidget()函数用来销毁一个容器控件中的子控件,通过在定时器函数中调用该函数可以将PtRaw容器控件中使用的PtLine子控件绘制的码盘擦除,再利用PtReRealizeWidget()函数使PtRaw控件实现,从而调用绘图函数,重绘频率取决于定时器的Timer Repeat值。
Photon事件空间由若干个平面组成[4],如图2所示,事件在某个平面生成并在事件空间中移动。比如,绘画事件从Application平面向Graphics平面移动;输入事件从Pointer/Keyboard平面向Root平面移动。为实现PtRaw控件画布销毁的第二个条件,可以在Photon事件空间中创建一个平面并使其发生一个矩形的Ph_EV_EXPOSE事件,在它向Root平面穿梭的过程中移走了Application平面上的区域,使得PtRaw控件自动调用绘图函数实现重绘。
按照上述方法绘制航向、方向舵、舯水平舵、艉升降舵码盘和水下航行器状态显示画面,编写回调函数,系统初始化函数,即可完成系统的界面设计。
2.2.3 主程序设计
为避免代码的重复编译,提高程序执行效率,本文以界面程序中已设定的回调函数为基础对系统主程序进行了设计,减小了编程工作量。根据嵌入式训练系统的功能要求,进行的程序设计如下:
(1) 六自由度运动模型程序设计。由于运动模型的精度直接关系到嵌入式训练系统的训练效果,本文采用了国际通用的六自由度空间运动方程[5],包括轴向力方程、侧向力方程、垂向力方程、横摇力矩方程、纵倾力矩方程、偏航力矩方程和辅助方程,利用数学方法将方程化为[u=f1]的形式,通过积分解算程序解算出状态向量[u,v,w,p,q,r,φ,θ,ψ,ξ,η,ζ],这些积分值再与方向舵、舯水平舵、艉升降舵的舵角一起作为六自由度模型新的初始条件参与下一时刻状态向量的求解。
(2) 舵机模型程序设计。目前,通常采用的舵机数学模型[6]为:
[TEδ=KE(δe-δ)]
式中:[δ]为实际舵角;[δe]为指令舵角;[TE]为舵机时间常数;[KE]为舵机的控制增益。考虑到舵机的实际情况,在模型中加入舵角及转舵速度限制,模型程序如下:
double rudder_model(double angle,double angle_given,double angle_limit)
{ double diff,deter;
int i;
for (i=0;i<100;i++)
{
diff= angle_given ?angle;
deter=0.4*diff; //舵机模型,TE取2.5,KE取1
if(deter>3.14/90) deter=3.14/90;
//转舵速度限制..3(°)/s
if (deter