唐 浩,代少升
(重庆邮电大学 信号与信息处理重点实验室,重庆 400065)
21世纪是后计算机时代,人们每天都会接触很多的嵌入式产品,手机、PDA等手持式信息设备发展迅速。这些设备的关键在于人机交互技术的体现,所以一个十分友好的图形用户界面(GUI)是必不可少的。
目前嵌入式Linux的主流GUI系统主要有MiniGUI,MicroWindows,OpenGUI,Qt/Embedded 等[1],这些 GUI 在接口定义、体系结构、功能特性等方面存在很大差别。MiniGUI具有良好的软件架构,通过抽象层将其上层和底层操作系统隔离开来,开发的重点在于窗口系统,但由于支持力量比较薄弱,其维护和再开发成本不可预计。MicroWindows以较小的资源消耗、通用的帧缓冲(FrameBuffer)技术、灵活的分层设计模式和丰富的API支持等特点获得广泛的关注,但其图形引擎无任何硬件加速能力,算法低效,代码质量较差。OpenGUI基于用汇编语言实现的X86图形内核,提供了高层的C/C++图形/窗口接口,它的资源消耗小,但可移植性差,不支持多进程。
Qt/Embedded[2]是一个多平台的C++图形用户界面应用程序框架,易扩展,可移植性好,支持多个GUI平台的交互开发。从个人消费电子到工业控制设备,Qt/Embedded被广泛地应用于各种嵌入式产品和设备中。
Qt/Embedded是著名的Qt库开发商Trolletch公司(2008年6月被诺基亚公司收购)开发的图形化界面开发工具Qt的嵌入式版本。Qt/Embedded采用Server/Client结构,延续了Qt在X上的强大功能,在底层摒弃了Xlib,仅采用FrameBuffer作为底层图形接口。同时将外部输入设备抽象为keyboard和mouse输入事件,底层接口支持键盘、鼠标、触摸屏以及用户自定义的设备等[3]。
Qt/Embedded的类库完全采用C++封装,控件资源丰富,可移植性较好,开放的源码使得开发人员可以在GPL许可协议下自由地进行嵌入式GUI应用程序的移植与开发。Qt/Embedded移植与开发总体流程如图1所示。
笔者采用广州友善之臂公司设计的Micro2440开发板作为硬件平台,该开发板由核心板与底板组成。核心板上集成了三星公司400MHz的微处理器S3C2440,64Mbyte的SDRAM,64Mbyte NAND Flash以及2Mbyte NOR Flash。底板上则集成了一些常规外设接口。在软件方面,使用Linux-2.6.13稳定内核的操作系统,根文件系统为缺省安装的文件系统,采用基于arm-linuxgcc-3.4.1的函数库。
整个系统软件由引导装载程序(U-Boot)、设备驱动(包括帧缓冲)、嵌入式 Linux内核、文件系统(YAFFS)以及基于 Qt/Embedded的应用程序组成[4]。系统平台结构如图2所示。
搭建编译平台是嵌入式GUI的必要工作。Qt/Embedded的软件开发环境主要包括嵌入式Linux操作系统、软件开发工具链以及相关源码包。本文的开发环境是在个人PC上安装VMware Workstation 6.5.1和Red Hat Linux 9.0操作系统,内核版本是2.6.13,与目标板上运行的版本一致。采用的交叉编译器为armlinux-gcc-3.4.1,源码包为qt-embedded-linux-opensource-src-4.5.3和 qt-x11-opensource-src-4.5.3。
在PC机上编译好的qt-x11可以生成Qt开发工具,如用户界面编译器(UIC)与虚拟帧缓冲服务器(QVFB),作为交叉编译环境的支持。虚拟环境搭建过程如下:
1)在PC平台文件系统中建立工具包目录,将源码包分别用tar命令解压并放置其中。
2)进入qt-x11目录,在终端键入./configure命令对qt-x11安装环境进行配置,根据源码包配置选项和系统情况生成makefile文件,为make做准备。
3)配置完成以后,键入make命令,从makefile中读取指令进行编译,用来创建库文件,编译例程和指南,需要等待一段比较长的时间。
4)编译完成之后,进入tools目录下的qvfb目录,键入make对其进行编译。最后回到qt-x11目录,键入make install进行安装。
5)make install完成之后,会在/usr/local目录下生成一个Trolltech目录,这就是qt-x11-opensource-src-4.5.3安装后所在目录。将/usr/local/qt/qt-x11-opensource-src-4.5.3/tools/qvfb目录下的qvfb相关文件拷贝到/usr/local/Trolltech/Qt-4.5.3/bin目录下。至此X11环境就搭建好了。
通过qt-x11提供的库和开发工具,可以进行Qt应用程序的开发,但是若需要在目标板上运行该程序,则还需使用qt-embedded库对该程序进行交叉编译,才能得到在ARM平台上运行的可执行程序。这就需要搭建qt-embedded交叉编译环境,其实现过程如下:
1)安装交叉编译器。工具包目录中键入tar xvzf arm-linux-gcc-3.4.1.tgz-C/,执行该命令将arm-linuxgcc安装到/usr/local/arm/3.4.1。然后设置路径变量,修改/etc/profile文件,在最后一行添加export PATH=/usr/local/arm/3.4.1/bin:$PATH。
2)进入qt-embedded目录,键入./configure-embedded arm-xplatform qws/linux-arm-g++-depths 4,8,16,32,配置参数指定 ARM 平台,并支持 4,8,16,32 位的显示颜色深度。
3)使用make命令进行编译,用来生成qt-embedded库。
4)使用make install进行安装。完成后,qt-embe-dded被安装在/usr/local/Trolltech/QtEmbedded-4.5.3目录下。
Qt/Embedded应用程序在S3C2440平台上的运行需要有qt-embedded库支持。在开发板的根目录下新建如下目录:
/usr/local/Trolltech/QtEmbedded-4.5.3/bin//安装运行库文件
/usr/local/Trolltech/QtEmbedded-4.5.3/lib/fonts//安装字体库文件
把PC上对应目录下交叉编译后生成的qtembedded库文件和字体文件,分别拷贝到上述目录中。注意,运行库文件一般只拷贝libQtGui.so.4,libts-0.0.so.0,libQtCore.so.4,libQtNetwork.so.4,如果文件是到共享库的链接文件,则把该共享库也要拷贝上,字体库则需拷贝一种就可以了。设置开发板环境变量:
export QTDIR=/usr/local/Trolltech/QtEmbbed-4.5.3
export QPEDIR=/usr/local/Trolltech/QtEmbedded-4.5.3
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
Qt是一个创建GUI程序的C++类库,编写Qt应用程序的主要工作是基于已有的Qt类去编写用户类。笔者以发布一个图片浏览工具(ImgViewer)为例,简单地介绍Qt/Embedded应用程序的开发过程。
强大的工具支持是进行Qt/Embedded图形用户开发的优势所在。除了前面提到的QVFB和UIC工具外,Qt designer(图形设计器)工具为GUI窗口组建,提供了一种可视化的设计能力,非常方便高效;qmake工具能为不同平台的开发项目创建makefile配置文件;编程助手assistant能随时随地给编程带来帮助。
笔者采用Qdevelop4.4.3来编写Qte程序。Qdevelop是一个跨平台集成开发环境,完全致力于Qt4的开发。
Qt/Embedded源程序一般应该包含以下文件:1个主程序文件(main.cpp)、多个源程序文件(source.cpp)与对应的头文件(source.h)以及用来生成makefile的项目文件(.pro)。在本次开发中,并没有使用Qt designer来进行可视化窗口设计,完全借助Qdevelop纯代码进行编写,这样能更好地体会Qt/Embedded GUI设计的精髓所在。基本操作步骤如下:
1)编写头文件imgviewer.h。在Qdevelop中新建工程imgviewer.pro,并添加头文件imgviewer.h。头文件定义了实例中需要用到的各种窗体控件,包括菜单(QMenu)、工具条(QtoolBar)、动作(Qaction)以及各种操作的槽函数(slots)。
2)编写源文件imgviewer.cpp。源文件中设置了字体,规定了窗口属性,并且创建了动作、菜单和工具条等一系列的实现函数。这里会接触到Qt最重要的特性:信号与槽机制(signal&slot)。信号与槽机制提供了任意两个Qt对象之间的通信机制,信号会在某个特定情况或动作下被触发,槽是用于接收并处理信号的函数。其常用格式为 bool QObject::connect(Object1,SIGNAL(signal1),Object2,SLOT(slot)),以及与这个函数对应的disconnect函数,可以将信号和槽断开连接。下面介绍一段简单的程序,该程序设置了打开单个文件这一动作:
openFileAction=new QAction(QIcon(":/images/openfile.png"),tr("Open"),this);//创建一个 Open 动作,并调用openfile.png图标,图标位于资源库images文件夹下。
openFileAction->setStatusTip(tr("Open File"));//设置该图标的状态提示为"Open File"。
connect(openFile-Action,SIGNAL(triggered()),this,SLOT(slotOpenFile()));//连接信号与槽,触发 openFileAction这一动作时,将进行slotOpenFile()这一过程的处理。
3)编写主函数main.cpp。Qt/Embedded应用程序应该包含一个主函数,该函数是应用程序的入口点。结合imgviewer.h和imgviewer.cpp,可以看到所有应用程序开发主函数main.cpp编写的框架结构:
#include"imgviewer.h"
#include
//QApplication包含了Qt图形化应用程序的各种资源、基本设置、控制流以及事件处理等。若是Qt的非图形化应用程序,则需包含
4)生成makefile文件及编译链接生成可执行文件。借助qmake工具可以生成makefile文件,实现过程为:qmake-o Makefile imgviewer.pro。然后在命令行下输入make命令对整个工程进行编译,就能生成X86架构的二进制文件,这便是QVFB能执行的应用程序。如果再用Qt/Embedded的库对整个工程进行交叉编译链接,就能得到在S3C2440平台上运行的可执行文件。
将交叉编译好的可执行程序imgviewer拷贝进开发板/usr/local/Trolltech/QtEmbedded-4.5.3/bin目录下,在终端下键入./imgviewer,即可运行程序。运行结果见图3。
嵌入式技术的关键在于人机交互技术的体现,基于Qt/Embedded的GUI为嵌入式Linux系统用户提供了良好的使用和交互环境。笔者通过一个简单的应用程序,对Qt/Embedded在S3C2440平台下的移植与开发进行了详细介绍,为类似的GUI程序开发提供了一个参考。
[1]AHN S H,SUL D M,CHOI S C,et al.Implementation of lightweight graphic library builder for embedded system[C]//Proc.The 8th International Conference on Advanced Communication Technology.Phoenix,USA: IEEE Press,2006:166-168.
[2]Trolltech.Online reference documentation[EB/OL].[2010-05-05].http://doc.trolltech.com/.
[3]梅宽勤.基于Qt/Embedded的图像用户界面移植[D].上海:复旦大学,2007.
[4]赵拯宇,张雪英,金刚.Qt/Embedded和Qtopia在OMAP5912平台上的移植及应用[J]. 仪器仪表用户,2009,16(2):108-110.
[5]孙琼.嵌入式Linux应用程序开发详解[M].北京:人民邮电出版社,2006.
[6]成洁,卢紫.Linux窗口程序设计[M].北京:清华大学出版社,2008.
[7]BLANCHETTE J,SUMMERFIELD M.C++GUIQt 4编程[M].2版.闫锋欣,曾泉人,张志强,译.北京:电子工业出版社,2008.