作者:小野狼
-- 发布时间:2009-8-31 16:31:10
-- 嵌入式Linux环境下MiniGUI的研究与移植
前言
近年来随着嵌入式设备与市场需求的广泛结合,手机、PDA、DVD播放机等产品的应用对可视化操作界面的简洁和方便提出了更高的要求,这都需要一个稳定可靠的高性能GUI系统来提供支持。图形用户界面(Graphic User Interface,简称GUI)的广泛流行是当今计算机技术的重要成就之一,它极大地方便了非专业用户的使用,人们可以通过窗口、菜单方便地进行操作。由于嵌入式系统实时性要求高,同时嵌入式系统硬件配置又有限,所以对轻型GUI的需求更加突出。另外,嵌入式系统往往是一种订制设备,它们对GUI的需求也各不相同,因此GUI也必须是可订制的。综上所述,嵌入式系统对GUI的基本要求应包括轻型、占用资源少、高性能、高可靠性以及可配置。MiniGUI是目前比较常用的几种GUI系统之一,与其他的GUI相比,MiniGUI最显著的特点就是轻型、占用资源少,而且在这几年的发展里,MiniGUI已经非常成熟和稳定了,在许多产品和项目中都已得到了实际应用。
1 MiniGUI的特点和体系结构
1. 1 MiniGUI的特点
MiniGUI是由原清华大学教师魏永明主持开发的轻量级图形系统,是一种面向嵌入式或实时系统的图形用户界面支持系统。它遵循GPL公约,是基于SVGALib及LinuxThread库的多窗口GUI支持系统。能跨多种操作系统,主要运行于linux及一切具有POSIX线程支持的POSIX兼容系统,包括普通嵌入式Linux、eCos、uC/OS-II、VxWorks等系统,是国内最早的自由软件之一。
MiniGUI的主要特点有:
(1) 遵循GPL条款的纯自由软件;
(2) 提供了完备的多窗口机制;
(3) 多字符集和多字体支持,目前支持ISO8859-1、GB2312及Big5等字符集,并且支持各种光栅字体和TrueType、Type1等矢量字体;
(4) 全拼和五笔等汉字输入法支持;
(5) BMP、GIF、JPEG及PCX等常见图像文件的支持;
(6) Windows的资源文件支持,如位图、图标、光标、插入符、定时器及加速键等;
(7) 可移植性好。
1.2 MiniGUI的体系结构
1.2.1多线程的分层设计
从整体结构上看,MiniGUI是分层设计的,结构如图1所示。在最底层,GAL(图形抽象层)和IAL(输入抽象层)及鼠标和键盘的驱动;中间层是MiniGUI的核心层,包括窗口系统必不可少的各个模块;最顶层是API,即编程接口。GAL和IAL为MiniGUI提供了底层的Linux控制台或者X Window上的图形接口以及输入接口,而Pthread用于提供内核级线程支持的C函数库。利用GAL和IAL,大大提高了MiniGUI的可移植性,并且使程序的开发和调试变得更加容易。可以在X Window上开发和调试自己的MiniGUI程序,通过重新编译就可以让MiniGUI应用程序运行在特殊的嵌入式硬件平台上。
MiniGUI本身运行在多线程模式下,它的许多模块都以单独的线程运行,同时,MiniGUI还利用线程来支持多窗口。从本质上讲,每个线程有一个消息队列,消息队列是实现线程数据交换和同步的关键数据结构。一个线程向消息队列中发送消息,而另一个线程从这个消息队列中获取消息,同一个线程中创建的窗口可共享同一个消息队列。一个线程向消息队列中发送消息,而另一个线程从这个消息队列中获取消息,同一个线程中创建的窗口可共享同一个消息队列。利用消息队列和多线程之间的同步机制,可以实现下面要讲到的微客户/服务器机制。
1.2.2微客户/服务器结构
在多线程环境中,与多进程间的通讯机制类似,线程之间也有交互和同步的需求。比如, 用来管理窗口的线程维持全局的窗口列表, 而其他线程不能直接修改这些全局的数据结构, 而必须依据“先来先服务”的原则,依次处理每个线程的请求,这就是一般性的客户/服务器模式。MiniGUI利用线程之间的同步操作实现了客户线程和服务器线程之间的微客户/服务器机制。
2 开发环境
H2410EB开发板由北京恒颐高科技术有限公司设计开发,它基于Samsung公司的S3C2410A20嵌入式ARM处理器。S3C2410A20内嵌 ARM920T 核,带有全性能的MMU,具有高性能、低功耗、低成本、小体积等优点,适用于手持设备、汽车等领域。
H2410EB除带有大容量的SDRAM和Flash以外,还扩展了RS-232C串行接口、10Mbps以太网接口、触摸屏接口、音频输入/输出接口、USB Host、USB Slave、UART接口、IIC接口、用户自定义键盘、LCD显示器,方便用户使用和进行参考设计。它支持嵌入式Linux操作系统的运行,支持MP3/MPEG播放、GUI、Web 服务及其它服务,同时可根据用户需求开发特定软件与设备驱动程序。
操作系统采用裁减后的Linux,Linux Kernel版本为v2.4.18,系统使用的交叉编译器是arm-Linux-gcc。另外,还有驱动程序源码和测试程序源码等代码模块。
3 MiniGUI的移植
本文中使用的主机系统为Red Hat Linux 9.0,移植目标系统为Linux2.4.18,MiniGUI的版本是1.6.9。在主机上交叉编译MiniGUI链接库,然后将针对目标机编译的库文件,与根文件系统一起烧写到目标板的RAM空间,以后将运行在目标板上的图形用户界面直接链接到该库,脱离主机独立运行。
3.1 Linux交叉编译环境的构建
GUI的编译通常都是在PC机上执行的,也就是说,编译器本身能够在PC机上执行,同时编译源代码生成的二进制文件必须能在目标机上执行,这类编译器通常称为交叉编译器。对于ARM平台,我们安装了cross-arm-binutils-2.10-1.i386.rpm、cross-arm-gcc-2.95.3
-2.i386.rpm、cross-arm-glibc-2.1.3-2.i386.rpm这三个包。这些包都可以从网上免费获取。arm-binutils这个包一般包含了一些针对ARM平台的二进制工具,比如arm-strip、arm-ar等命令;arm-glibc这个包包含的是标准C的函数库的ARM的版本以及对应的头文件;arm-gcc中包含的则是生成ARM平台代码的x86上的交叉编译器。执行rpm命令将这些包安装到PC机上,若不在系统默认搜索目录下,则必须将安装目录加到系统的PATH环境变量中,这样在每次编译时系统才能找得到编译器。
以root用户登陆Linux系统,在主机上用rpm指令安装交叉编译工具,arm-linux-gcc将被安装到/usr/local/arm/2.95.3/下面。此时,gcc为 /usr/local/arm/2.95.3/bin/arm-linux-gcc,而它的include为 /usr/local/arm/2.95.3/arm-linux/include,对应的lib为 /usr/local/arm/2.95.3
-/arm-linux/lib。然后,在你的bashrc 中添加环境变量即可
vi .bashrc
最后一行加入:export PATH=$PATH:/usr/local/arm/2.95.3/bin路径
保存退出后执行source .bashrc
另外需要注意的是,编译时所用的函数库版本要与目标版上运行时所用的函数库版本一致。经过上述步骤,就已经建立了交叉编译环境,接下来的就是进行MiniGUI的选项配置和交叉编译。
3.2 MiniGUI的配置和交叉编译
我们可以从网上http://www.minigui.com/download)免费得到MiniGUI-1.6.9的资源文件压缩包,MiniGUI1.6.9的源程序包包括以下三个部分:
libminigui-1.6.9.tar.gz-MiniGUI函数库源代码;
miniguires-1.6.9.tar.gz-MiniGUI所使用的资源,包括基本字体、图标、位图、输入法等;
mde-1.6.9.tar.gz-MiniGUI的综合演示程序。
3.2.1 配置MiniGUI选项
把函数库文件包解压:tar zxf libminigui-1.6.9.tar.gz,进入libminigui-1.6.9这个目录,执行make menuconfig命令
-system wide options中选择Build MiniGUI-Lite,并取消Use incore (built-in) resource选项;
-Gal engine options 图形引擎,根据目标机的显示方式确认,这里只勾选了 NEWGal engine on Linux FrameBuffer console,其它的不选;
-Ial engine options输入引擎,可用触摸屏只选了SMDK2410 Touch Screen;
-Font Options 中取消选择Var bitmap font,可能是因为Bug的原因,当选择了该选项后,编译测试例子的时候总是提示unreferenced vfb_Courier …之类的错误;
-Image options选择了Includes SaveBitmap-related functions。GIF、JPG、PNG图形格式也勾选上;
-Development environment options 里使用Linux平台,arm-linux-gcc编译器,安装路径设置在 /usr/local/arm/2.95.3/arm-linux/。
其它的用缺省选项就可以了,保存退出。
3.2.2 MiniGUI函数库的安装和编译
进入目录libminigui-1.6.9,再运行./configure脚本:
CC= arm-linux-gcc./configure——prefix=/mnt/nfs/local——build=i386-linux——host=arm-linux——target=arm-linux——disable-lite——disable-micemoveable——disable-cursor在这里,CC是用来指定所使用的编译器,arm-linux-gcc即为安装到主机上的交叉编译工具。另外,
--prefix为MiniGUI函数库的安装目标路径
--build是指执行编译的主机
--host交叉编译后的程序将运行的系统
--target是运行该编译器所产生的目标文件的平台
--disable-lite建立MiniGUI-Threads版本的应用程序
--disable-micemoveable禁止窗口移动
--disable-cursor由于系统采用触摸屏,所以用此选项用来关闭鼠标光标显示
如果运行./configure脚本成功通过,就可继续进行下面的编译了,执行make和make install命令编译安装libminigui。这里要注意的是,执行make install命令时要切换到Root用户权限下,不然安装时没法把文件装到指定目录下。安装成功后,MiniGUI 的函数库和头文件以及配置文件等资源将被安装到/usr/local/arm/2.95.3/arm-linux/目录中,具体情况为:函数库被装在lib/ 子目录中;头文件被装在include/ 子目录中;手册被装在man/ 子目录中;配置文件被装在etc/ 子目录中。
3.2.3 MiniGUI资源的编译安装
主机上解压资源文件:tar zxf miniguires-1.6.9.tar.gz,可生成miniguires-1.6.9目录。在安装之前先要修改目录中的configure.linux文件,执行vi configure.linux打开文件,把prefix选项部分的默认值 /usr/local/ 改为 /usr/local/arm/2.95.3/arm-linux/,这样运行make install安装命令后MiniGUI资源将被安装到目标系统中的/usr/local/arm/2.95.3/arm-linux/lib/minigui-
/res的目录下。
3.2.4 实例程序的编译安装
解压mde-1.6.9.tar.gz并进入该目录,修改目录下配置文件configure.in,把其中的AC_CHECK_HEADERS(minigui/commmon.h, have_libminigui=yes, foo=bar)改为
AC_CHECK_HEADERS($prefix/include/minigui/common.h,have_libminigui=yes,foo=bar),来指定交叉编译时搜minigui的头文件路径,防止编译时系统找不到头文件;在所有LIB="$LIB后加入–L{prefix}/lib来指定编译时所需要库文件的路径。并将libpopt-dev-arm-cross-1.6.tgz解压所生成的头文件和库文件分别放入目标目录的include和lib中,用以支持mde中程序在ARM下的交叉编译。
然后执行./autogen.sh,重新生成configure脚本,使用上面配置的脚本然后执行make命令,即可完成实例程序的编译。
4 拷贝MiniGUI资源到开发板
编译完MiniGUI和实例程序之后,需要把MiniGUI库、资源和应用程序拷贝到为目标机器准备的文件系统目录中,然后生成文件系统映像,再下载到目标板上运行。可以通过串口、USB口或以太网口将文件系统映像下载到目标机器中。如果发现子目录lib 中的MiniGUI 库文件很大,很难全部拷贝到开发板上的话,可以对库文件执行arm-linux-strip操作,arm-linux-strip指令会除去文件中的调试信息,使文件体积大大缩小。另外需要注意的是,有些库函数是链接文件,如果单纯的拷贝,会将原先的链接信息丢失,造成不必要的麻烦。使用tar命令将所需拷贝的资源打包,其中包括etc子目录下的配置文件MiniGUI.cfg;lib 子目录下的libmgext-1.6.9.so.0.0、libminigui-1.6.9.so.0.0、libvcongui-1.6.9.so.0.0和minigui子目录;mde-1.6.9目录下的可执行程序。将这些资源烧写进ramdisk文件系统中,解压后将MiniGUI的配置文件MiniGUI.cfg放入/usr/local/etc目录中,MiniGUI的库文件放入/usr/local/lib目录中。在执行程序之前,还有一件重要的事情要做,就是在开发板上的Linux中配置好MiniGUI的运行环境。
5板载Linux的环境配置
MiniGUI可以使用多种图形引擎进行图像显示,有qvfb、SVGALib、LibGGI等等,当然也可以自己编写一个图形引擎供MiniGUI使用。这里我们使用qvfb来作为MiniGUI的图形引擎进行图像显示。qvfb(vitural framebuffer)是在宿主机上模拟帧缓冲的,它是X Window用来运行和测试应用程序的系统程序,允许我们在桌面及其上开发Qt嵌入式程序,而不需要在命令台和程序之间来回切换。qvfb使用了共享存储区域(虚拟的帧缓冲)来模拟帧缓冲并且在一个窗口中(qvfb)模拟一个应用来显示帧缓冲,显示的区域被周期性的改变和更新。通过指定显示设备的宽度和颜 {MOD}深度,虚拟出来的缓冲帧和物理的显示设备在每个像素上保持一致。这样我们在每次调试应用时不需要总是刷新嵌入式设备的FLASH存储空间,从而加速了应用的编译、连接和运行周期。
首先对qvfb进行安装,可以从这里下载http://www.minigui.com/downloads/dep-libs/qvfb
-1.0.tar.gz),下载下来后进行解压:tar zxf qvfb-1.0.tar.gz并进入到qvfb-1.0目录,执行./configure脚本后即可用make和make install命令进行编译安装。
更改MiniGUI的配置文件MiniGUI.cfg设置设备驱动程序,设置显示区域及字体等内容。修改/usr/local/etc目录下的配置文件MiniGUI.cfg,将其中的驱动引擎gal_engine和ial_engine设置为qvfb,再将其中qvfb的defaultmode设置为合适的显示模式。然后把qvfb加到可执行路径中去,执行vi .bashrc命令,在 .bashrc最后面加上export PATH=/usr/local/arm/2.95.3/bin -:$PATH,保存退出后用source .bashrc命令执行一下即可。
在X Window中,打开一个终端仿真程序,执行qvfb &命令。在qvfb中选中File Configure,将qvfb设置成嵌入式开发系统的液晶屏的大小。合理设置MiniGUI的配置文件后,接着就可以运行MiniGUI应用程序了。
执行应用程序顺利的话,屏幕上可以看到程序的运行界面。至此,MiniGUI已经成功移植到目标系统上。此后,我们可以根据需要,继续修改MiniGUI库函数及各种资源,并且编写自己的应用程序,使图形用户界面更加完善。
6 结束语
随着嵌入式产品应用领域的日益增长,开发出优秀的人机交互界面,是嵌入式发展的趋势,拥有广阔的市场前景。MiniGUI可以稳定可靠的运行在Linux系统下,通过上述具体的移植和后续的MiniGUI下嵌入式软件的开发过程,能快速构建一个嵌入式可视化软件系统,相信这种嵌入式系统将会得到越来越多的应用。