本文是用 Word 写的,本来想当成附件发上来,结果系统说“发贴数大于10篇才能上传附件!”,让我暴汗~~~~~
所以就直接 Copy 上来了,有Word 中有一些加红,加黑表示要注意的地方这里显示不出来,大家将就着看吧,呵呵,有什么错误希望大家指出,谢谢

MiniGUI 1.3.3 移植详解

作者:大漠孤狼   E-Mail:yuqiang0107@126.com

最 近移植了 MiniGUI 1.3.3 到一个开发板上,中间遇到许多问题,在论坛上发问题,结果也没多少人回我,就算偶尔有回的,基本上回答也没有什么用,网上找不到一个完整的移植文章,所以 就决定把自己这次移植摸出来的一些方法写出来,给像我一样的小菜鸟做个参考吧。本文不教你怎么写驱动,只是教怎么样在最短的时候在你的PC机上搭建起开发 环境,同时在你的板子上跑起MiniGUI 来,这样你就可以在PC上开发好程序,调试完毕,然后交叉编译一下,直接Copy到板子上就可以了。

首先,你需要下载的MiniGUI 的包:
http://www.minigui.com/download/libminigui-1.3.3.tar.gz    
http://www.minigui.com/download/minigui-res-1.3.3.tar.gz      
这两个包的下载需要你在www.minigui.com  上注册过才可以下载,免费注册的,自己去下吧
http://www.minigui.com/downloads/minigui13/mde-1.3.0.tar.gz    图形界面程序
http://www.minigui.com/downloads/minigui13/mg-samples-1.3.0.tar.gz  一些小例子

好,首先就下载这几个包吧,后面还有需要下载的包,后面再说

1.PC环境的搭建

首 先你需要一个 Linux 环境,我安装的是 RedHat 9.0  安装时记着选 everything ,这样可以避免到时候编译少了东西。这里搭建的环境是让 MiniGUI 在你的 PC 上可以跑起来,这样以后你开发程序就可以只在 PC 上开发,调试好,最后交叉编译一下放到板子上就行了。后面会讲怎么为板子编译MiniGUI ,耐心的看吧:)

首先建立自己的开发目录

[Root]#  mkdir /opt
[Root]#  cd /opt
[Root]# mkdir st2410             //这个是我的板子,
[Root]# chmod 777 st2410         //给一般用户操作权限
[user]#  cd /opt/st2410           //进到目录中去,在这个目录下工作,用普通用户来工作

把 libminigui-1.3.3.tar.gz 解开
[user]# tar  zxf  libminigui-1.3.3.tar.gz
[user]# tar zxf minigui-res-1.3.3.tar.gz

编译 libminigui  ,这个是 minigui 运行所必需的库文件,必须编译成功
[user]# cd libminigui-1.3.3
[user]# ./configure                 //最简单的编译方式,让它自己去配置 ,这里采用缺省的Thread 模式而不是Lite模式,因为这种方式在 PC 机上使用最方便,后面移到板子上再改成 Lite 模式即可

注意屏幕上的输出,特别是下面几条

checking for FrameBuffer console support... yes
checking for pthread library... yes
checking for TT_FreeType_Version in -lttf... yes
checking for T1_InitLib in -lt1... no
checking for jpeg_std_error in -ljpeg... yes
checking for png_check_sig in -lpng... yes


其中 –lttf   –lpng  必须是 yes ,不然后面你的程序肯定会有问题,如果这里不是 yes 的话,肯定是你的 Redhat 9 安装不对,告诉过你安装时选 everything ,你选了吗???

其中 ttf 库是对 TrueType 字体的支持,png 库是对 png 图形的支持,MiniGui 里都需要这两个,在后面为板子交叉编译的时候也需要这两个,不然你的程序跑不起来,切记切记。

好了,现在通过了,下面是编译了
[user]# make
接来来就是漫长的等待了,让它慢慢的编译吧,呵
[user]#  su         //切到 Root 用户权限下,不然安装时没法把文件写到你的 /usr/local 目录下
[Root]# make install

好了,库安装完毕,下面是安装资源
[Root]# cd /opt/st2410/minigui-res-1.3.3
[Root]# make install

OK,基本的安装完成了,现在检查一下
看看在你的目录  /usr/local/lib 下是不是有以下文件
libmgext-1.3.so.3 -> libmgext-1.3.so.3.0.0
libmgext-1.3.so.3.0.0
libmgext.a
libmgext.la
libmgext.so -> libmgext-1.3.so.3.0.0
libminigui-1.3.so.3 -> libminigui-1.3.so.3.0.0
libminigui-1.3.so.3.0.0
libminigui.a
libminigui.la
libminigui.so -> libminigui-1.3.so.3.0.0
libvcongui-1.3.so.3 -> libvcongui-1.3.so.3.0.0
libvcongui-1.3.so.3.0.0
libvcongui.a
libvcongui.la
libvcongui.so -> libvcongui-1.3.so.3.0.0

里面还有一个目录 minigui ,可以进到里面去看,分别为 minigui/res/ [bmp , cursor,icon ,…..] 好几个目录,里面有相应的文件
检查 /usr/local/include  里面是不是多了一个 minigui 目录,/usr/local/include/minigui 时面好多的 .h 文件,如下:

common.h  control.h  endianrw.h  fixedmath.h  mgext.h    mywindows.h  vcongui.h
config.h  dti.c      filedlg.h   gdi.h        minigui.h  skin.h       window.h

如果这里检查没有这些东西的话,那你前面的步骤肯定有问题,自己检查一下吧。


首先,修改你的 /etc/ld.so.conf 文件,在里面最后新加入一行 /usr/local/lib
然后执行 [Root]#  ldconfig
OK !


[Root]# vi /usr/local/etc/MiniGUI.cfg

在里面找到

[system]
# GAL engine
#gal_engine=fbcon
gal_engine=qvfb   //这里修改

# IAL engine
#ial_engine=console
ial_engine=qvfb    //这里修改

mdev=/dev/mouse
mtype=IMPS2

[fbcon]
defaultmode=1024x768-16bpp

[qvfb]
defaultmode=640x480-16bpp    //这里修改
display=0

保存一下,OK了!

现在你需要安装一个 qvfb ,因为 Redhat 9 里面没有,从下面地址下载
http://www.minigui.com/downloads/dep-libs/qvfb-1.0.tar.gz

老方法:
[user]# tar zxf qvfb-1.0.tar.gz
[user]# cd qvfb-1.0
[user]# ./configure
[user]# make
[user]# make install

在这个过程中如果出现 error while loading shared libraries: libqt-mt.so.3: cannot open shared object file
说 明你的系统少了 libqt-mt.so.3 这个库,还是回去检查一下,你安装时Redhat 时是否选了 everything ,或者在实际操作的过程中,这个库有可以被误删除掉,我就出现过,这时候你可以 google 一下 ,输入 libqt-mt.so.3 redhat 9 ,应该就可以搜到相应的 rpm 包,安装时

[root]# rpm –i --force [你的包名]   就OK了  

这里有个下载地址,可以试试,我是用讯雷下载的,别的工具没试过
ftp://ftp.pbone.net/mirror/www-ccrma.stanford.edu/planetccrma/mirror/redhat/linux/planetccrma/9/en/os/i386/qt33-3.3.3-0.1.rh90.ccrma.i386.rpm

注意:在你后面的操作过程中有可能会导致 libqt-mt.so.3 丢失,这时候只要重装一下就OK了

解决了这个问题后重复安装过程
[user]# ./configure
[user]# make
[user]# make install

OK ,环境搭建好了,下面是测试了:)

还记得前面让你下载的 mg-samples-1.3.0.tar.gz 这个包吧,这个就是一些例子,现在试试吧:)
[user]# tar zxf mg-samples-1.3.0.tar.gz
[user]# ./configure
[user]# make
[user]# cd src

看看 src 目录下是不是已经编译出可执行文件来了

现在来执行一下吧,首先把 qvfb 加到你的可执行路径中去
[user]# cd $HOME
[user]# vi .bashrc

在 .bashrc 最后面加上一句
export PATH="$PATH:/sbin:/usr/local/arm/2.95.3/bin:/usr/local/bin:/usr/local"  
保存退出,这里面有些路径是为以后用的,比如 /usr/local/arm/2.95.3/bin ,先加上吧:)
[user]# source .bashrc   //让它执行一下,当然你也可以选择重启一下电脑,效果是一样的,呵

执行例子程序:
[user]# qvfb &           //在图形界面下执行,呵,别告诉我你只在命令行工作啊 :)
在 qvfb 中选 File  Configure  640x480 VGA   16bit   ,这样看起来舒服
[user]#  cd /opt/st2410/ mg-samples-1.3.0/src
[user]# ./helloword

OK ,这个时候你应该可以看到在 qvfb 中的执行效果了吧,记住:一定要先运行 qvfb ,并且设置 qvfb ,然后再运行你的程序,而且qvfb 每重启一次就需要重新设置一下,真麻烦

OK 你的 PC 环境搭建完毕了,你现在可以在 PC 上开发你的程序,并且编译,并在 qvfb  中执行,等完全验证它是正确的了,把它交叉编译一下,放到板子上去就可以了,呵呵:)


MiniGUI 还有一种执行方式,就是在 Console 下在 Framebuffer 上执行,这种方式太麻烦,在PC 上不推荐,你还是用 qvfb 执行吧,方便,呵

在FrameBuffer 上执行

修改 /usr/local/etc/MiniGUI.cfg 文件,如下

[system]
# GAL engine
gal_engine=fbcon
  //这里修改

# IAL engine
ial_engine=console
  //这里修改

mdev=/dev/mouse
mtype=none   //这里改成none,因为经常鼠标不正常

[fbcon]
defaultmode=1024x768-16bpp

[qvfb]
defaultmode=640x480-16bpp    
display=0



重 启动你的 RedHat 9 ,在出现 Grub 的时候按 E 键,在 kernel =…..      这一行的最后加入  vga=0x317  ,然后 Enter ,然后在 kernel=…  这一行上按 b  就可以了,这时候可以在启动时看到一个小企鹅的图标,OK

进去后,直接在 例子程序的目录下执行 ./helloword  就可以了 :)



2.为你的实验板进行交叉编译

OK,PC机的开发环境已经建立好了,下面就是要移植到我们的板子上去了,这里不介绍怎么移植 Linux 系统,假设你已经有一个可以在板子上跑的 Linux 系统了,并且已经有一个可以用的根文件系统了,并且已经有了板子相对应的LCD的驱动程序,这里介绍怎么在你的根文件系统里加上 MiniGUI ,使得你的板子有图形界面的显示。

要交叉编译,首先就得有交叉编译器,这里介绍 arm 板的交叉编译。不要自己去编译,直接去下载个就行了。
ftp://ftp.arm.linux.org.uk/pub/linux/arm/toolchain/cross-2.95.3.tar.bz2
记住这个 ftp ,最好的 arm 工具下载站,

下载回来,有35Mb,呵

安装交叉编译工具:
[Root]# mkdir  –p  /usr/local/arm
[Root]# cd /usr/local/arm
[Root]# tar jxf  cross-2.95.3.tar.bz2   //把工具直接解到压缩到这个目录下就安装完成了,简单吧:)

解压缩后生成一个 2.95.3 目录,里面在就是工具
记住,这时候的gcc为 2.95.3/bin/arm-linux-gcc   而它的 include 为 2.95.3/arm-linux/include ,对应的 lib 为 2.95.3/arm-linux/lib

也 就是说,你如果用 arm-linux-gcc 编译程序的话,它缺省的就找 2.95.3/arm-linux/include   2.95.3/arm-linux/lib  两个目录,而不是 /usr/include ,所以如果你要加什么 .h  .a .so 文件话,记着一定是加到这两个目录下去,不然编译器会告诉你找不到这些东西的

把可行程序的路径加入到 PATH 中去,还记得前面说过的改 .bashrc 文件吗?

[user]# cd $HOME
[user]# vi .bashrc

在 .bashrc 最后面加上一句
export PATH="$PATH:/sbin:/usr/local/arm/2.95.3/bin:/usr/local/bin:/usr/local"  

[user]# source .bashrc

OK ,交叉编译工具安装完了,够简单吧:)

MiniGUI 的编译需要一些库文件,缺省我们的 gcc 基本上都有这些库文件,所以不需要安装,可是现在要交叉编译了,交叉编译器可是不带这些库文件的,所以我们得首先自己编译这些库文件装到交叉编译器中去。

注意一点:库不一定要装最新的,库版本太新,MiniGUI 有可能不认识,像jpeg 库和 ttf 库就是这样,太新了反而用不了,所以要注意版本,以下的库都是我验证过可以和MiniGUI一起工作的,其它版本的库没试过,不保证能正确通过:)

首先安装 zlib 库,这个是后面的库的编译基础。
http://www.zlib.net/zlib-1.2.3.tar.gz  400多K,去下载吧,

下载到目录 /opt/st2410 下
[user]# tar zxf zlib-1.2.3.tar.gz

由于 zlib 库的configure 脚本不支持交叉编译选项,只好自己动用了,手动临时把 gcc 修改成指向我们的交叉编译器 arm-linux-gcc

[Root]# cd /usr/bin
[Root]# mv gcc gcc_back
[Root]# ln -s /usr/local/arm/2.95.3/bin/arm-linux-gcc ./gcc
[Root]# mv ld ld_back
[Root]# ln -s /usr/local/arm/2.95.3/bin/arm-linux-ld ./ld

OK ,修改完成后回到 /opt/st2410/zlib-1.2.3 目录下
[user]#  ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --shared  
注意:这里配置指向 /usr/local/arm/2.95.3/arm-linux/ 目录,会自动安装在 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录下,千万不要装错目录了,不然后面会找不到这个库的
[user]#  make
[Root]# make install

安 装完后检查一下目录 /usr/local/arm/2.95.3/arm-linux/ [include,lib] ,假如 include 中没有 zlib.h 之类的头文件,lib 中没有 libz.so.1.2.3 ,那就自己手动拷到这些目录下去,记着拷的时候把所有的 *.h  都需要拷过去,在拷库的时候用 cp –a libz.* /…./lib  就行,要用上 –a 选项


记着把刚才改过的 gcc 再改回去,不然后面会出错的!!!!!


安装 png 库,这个是用来显示 png 图形的,MiniGUI 里很多图都是 png 的,如果没有这个库,你的 MiniGUI 将无法正常工作,切记切记!

http://superb-east.dl.sourceforge.net/sourceforge/libpng/libpng-1.0.10rc1.tar.gz

还是那句话,库不要用最新的,最新的容易有问题,用这个老一点的就没问题了,呵

[user]# tar zxf libpng-1.0.10rc1.tar.gz
[user]# cd libpng-1.0.10rc1

Libpng 不提供有效的 configure 脚本,所以只好自己动手改 Makefile 文件了

[user]# cp scripts/makefile.linux  Makefile   //把 Scripts  下的一个 makefile 拷出来自己动手改
[user]# vi Makefile    // 自己动手改

CC=arm-linux-gcc    //修改这里

# where "make install" puts libpng.a, libpng.so*, png.h and pngconf.h
prefix=/usr/local/arm/2.95.3/arm-linux     //修改这里

# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=/usr/local/arm/2.95.3/arm-linux/lib   //修改这里
ZLIBINC=/usr/local/arm/2.95.3/arm-linux/include   //修改这里

好了,保存,然后去编译吧

[user]#  make
[user]#  make install

如果有错误,检查你前面的步骤哪个没做对 :) 尤其是 zlib 的安装

还是前面说的,检查 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录中有成功安装否,如果没有安装成功,那就自己把编译出来的东西拷过去。记着,*.h 和 .so 的文件都要拷。


OK,现在来安装 jpeg 库

ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz    自己去下载,速度暴慢

[user]# tar zxf jpegsrc.v6b.tar.gz
[user]# cd jpeg-6b
[user]# ./configure –help    //可以查看它的配置选项

首先在本机上编译一下,主要是它的 configure 文件设计得有问题,得先用 gcc 编译一个 dummy.c 的文件,然后才能后面编译,不然的话就会出现 libtool 找不到之类的错误

[user]# ./configure --enable-shared --enable-static

本机正常编译通过以后,[user]# make clean 清除掉,然后执行交叉编译

一 般情况下用 [cdp@cdpserver jpeg-6b]$ ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --host=arm-linux --enable-shared --enable-static

--host=arm-linux  来指定交叉编译选项,可是这里死活它不认,所以改用别的方法,如下

[user]# ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ CC=arm-linux-gcc --enable-shared --enable-static

[user]# make

安装前需要在 arm-linux 下建个目录,不然安装会出错

[Root]# mkdir –p /usr/local/arm/2.95.3/arm-linux/man/man1
[Root]# make install    // OK 了

一样,自己去检查一下安装是否成功 :)


最后安装 libttf 库,这个是 TrueType 字体的支持库,用来显示文字的。

http://nchc.dl.sourceforge.net/sourceforge/freetype/freetype-1.3.1.tar.gz

注意:MiniGUI 的文档说只支持 1.3.1 版本的 ttf 库,不要把版本弄错了 :)

这个库装起来最麻烦,全部自己手动编译,安装,下面一步一步来做吧:)

[user]# tar zxf  freetype-1.3.1.tar.gz       //老一套
[user]# cd freetype-1.3.1   //进到目录里去
[user]# mkdir –p /opt/st2410/libttf/extend   // 自己另外建立一个目录
[user]# cp freetype-1.3.1/lib/*  freetype-1.3.1/lib/arch/ansi/*  libttf/   //把有用的东西拷出来
[user]#cp freetype-1.3.1/lib/extend/*  libttf/extend/    把 extend 目录下的文件也拷出来

注意 cp 命令不要用 –r 选项,因为会把一些没用的东西出拷出来的

拷贝完成了,现在来自己手动编译了

[user]# cd libttf
[user]# arm-linux-gcc -c -fPIC -O2 freetype.c         //不要奇怪,对,我们只要编译这一个 .c 文件,因为它包括了其它所有的 .c 文件了,你可以自己查看它的内容  
[user]# arm-linux-gcc -c -fPIC -O2 -I./  extend/*.c   把 extend 下所有的 .c 文件全部编译
[user]# arm-linux-gcc --shared -o libttf.so *.o    生成最后的动态链接库,OK了

现在手动安装,得自己建立一下目录

[Root] mkdir –p /usr/local/arm/2.95.3/arm-linux/include/freetype1/freetype

[Root] cp *.h  extend/*.h   /usr/local/arm/2.95.3/arm-linux/include/freetype1/freetype
[Root] cp libttf.so  /usr/local/arm/2.95.3/arm-linux/lib

安装库完成,哈!

经过试验发现 MiniGUI 1.3.3 版本在链接 ljpeg lpng lttf 时老是要链接 /usr/lib 下的库,没办法,用老方法
[Root]# cd /usr/lib

[Root]# mv libjpeg.so   libjpeg.so_back
[Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libjpeg.so  ./libjpeg.so    //指向 arm 的库

[Root]# mv libpng.so   libpng.so_back
[Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libpng.so  ./libpng.so

[Root]# mv libttf.so   libttf.so_back
[Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libttf.so  ./libttf.so

完成以上工作后就可以编译 libminigui 了


[user]# cd libminigui-1.3.3
[user]#  make menuconfig                //就用图形界面来配置就好了,不要用一堆 –enable-xxx 之类的,太麻烦

如果在 make menuconfig 出错,去检查一下你的 gcc ,前面我们把它指向 arm-linux-gcc ,问一下,你改回来没有???????

下面是配置libminigui

在 System Wide Options 里如下:

  • Build MiniGUI-Lite        //用 Lite 方式编译,不是Thread 方式,这里适用于 PDA
    [ ]   Stand-Alone
    [ ] Use incore (built-in) resource        //建议不要选这个,老有问题
  • Unit of timer is 10ms
  • Cursor support
    [ ] User can move window with mouse   //建议别选这个,可以移动蛮烦人的
  • Mouse button can do double click
  • Build with debugging messages
    [ ] Trace messages of MiniGUI        //不要选这个,出来的Trace太多,看不过来
  • Include symbol name of messages

    在 GAL  engine Options 里

    (NEWGAL) GAL and its engines
  •   NEWGAL engine on Linux FrameBuffer console
    [ ]   NEWGAL engine on Qt Virtual FrameBuffer     //建议不要选这个,不然老让你用qvfb
    [ ]   NEWGAL engine on eCos LCD interface
  •   Dummy NEWGAL engine
  • Have console on Linux FrameBuffer


    在 IAL engine options 里

    [ ] EP7211-based board
    [ ] ADS Graphics Client
    [ ] iPAQ H3600 (also H3800)
    [ ] MPC823
    [ ] PX255B
    [ ] NEC VR4181
    [ ] Helio Touch Panel
    [ ] MT T800
  • SMDK2410 Touch Screen
    [ ] uClinux Touch Screen Palm/MC68EZ328
  • Dummy IAL engine
  • Native (console) input engine
    ---   Native IAL engine subdriver options
    [ ]   PS2 mouse
    [ ]   IntelligentMouse (IMPS/2) mouse
    [ ]   MS mouse
    [ ]   MS3 mouse
  •   GPM daemon


    在 Font Option 里

  • Raw bitmap font
    [ ] Var bitmap font  //千万不要选这个,不然会出现 unreferenced vfb_Courier8x8() 之类的错误
  • Incore font sansserif
  • Incore font courier
  • Incore font symbol
  • Incore font vgas
  • Qt Prerendered Font
  • TrueType font
    [ ] Adobe Type1 font


    在 Image Options 里

  • Includes SaveBitmap-related functions
    [ ] PCX file support
    [ ] LBM/PBM file support
    [ ] TGA file support
  • GIF file support
  • JPG file support
  • PNG file support

    在 Input Medthold Option 里

  • IME (GB2312) support
    [ ] IME (GB2312) Intelligent Pinyin module   //千万不要选这个,不然后面你的 mginit 程序一启动就崩溃了(Abort ,有点像 OOP 一样,显示所有的寄存器的值,然后Abort),暴不爽

    在 Development Environment Option 里

    (Linux) Platform
    (arm-linux-gcc) Compiler   //注意这里
    (glibc) Libc             //注意这里
    --- Installation options
    Path prefix: "/usr/local/arm/2.95.3/arm-linux"   //注意这里,我们把库装到交叉编译器的目录下
    --- Additonal Compiler Flags
         CFLAGS: ""
         LDFLAGS: ""

    其它的用缺省的选项就可以了,好了,现在退出,保存你的设置吧,然后它就开始检测你的系统了,注意下面的输出:

    checking for FrameBuffer console support... yes
    checking for TT_FreeType_Version in -lttf... yes      //True Type字体
    checking for jpeg_std_error in -ljpeg... yes           // jpeg 支持
    checking for png_check_sig in -lpng... yes           //png 图形支持,重要!!!
    checking for pow in -lm... yes


    这里的库应该都是显示为 yes 了,如果有 no 的话,回去检查前面你有哪步做得不对,不然的话编译后的东西可能没法正常执行,切记切记!!!

    如果这里通过了,那就OK了

    [user]#  make  //又是一个漫长的等待,呵
    [Root]#  make install

    注意:我们这里 make install 其实是给交叉编译器安装 libminigui 的库,你想,将来你需要编译为 minigui 开发的程序,这个程序总是需要链接库的吧,这些库因此也需要在交叉编译器中,不然你交叉编译的时候编译不过去 :)

    装 好了,到 /usr/local/arm/2.95.3/arm-linux  的 include lib 目录下去看看,是不是多了相应的 libminigui.so  libmgext.so  libvcongui.so    在 include 目录下多了一个 minigui 目录,里面有相应的头文件


    最后,安装 popt 库,这个库在编译 mde 程序时需要使用,不然编译没法通过 :)

    http://gd.tuwien.ac.at/utils/rpm.org/dist/rpm-4.1.x/popt-1.7.tar.gz  我是从这里下载的

    [user]#  tar zxf popt-1.7.tar.gz
    [user]# cd popt-1.7
    [user]# ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --host=arm-linux --enable-shared --enable-static
    [user]# make
    [Root]# make install

    一切很顺利,搞定了。
    交叉编译环境设置好了!

    OK ,下面是把 minigui 移植到你的板子上去了。

    我在 /opt 目录下建立了一个 rootfs 目录,即 /opt/rootfs  ,用来建立我的嵌入式系统的根目录,现在我需要把 minigui 的库文件放到里面去,

    建立目录
    [Root]# mkdir –p /opt/rootfs/usr/local/[lib,etc]

    把 /usr/local/arm/2.95.3/arm-linux/lib 中相应的库拷到 /opt/rootfs/usr/local/lib 目录下去
    下面是我拷的库文件:

    libjpeg.a          libmgext-1.3.so.3        libminigui.a   libpng.so.2            libttf.a                 libz.so
    libjpeg.la         libmgext-1.3.so.3.0.0    libminigui.la  libpng.so.2.1.0.10rc1  libttf.so              libz.so.1
    libjpeg.so        libmgext.a               libminigui.so  libpopt.a              libvcongui-1.3.so.3      libz.so.1.2.3
    libjpeg.so.62      libmgext.la              libm.so        libpopt.la             libvcongui-1.3.so.3.0.0  minigui
    libjpeg.so.62.0.0  libmgext.so              libm.so.6      libpopt.so             libvcongui.a             shared
    libm-2.2.3.so      libminigui-1.3.so.3      libpng.a       libpopt.so.0           libvcongui.la
    libm.a             libminigui-1.3.so.3.0.0  libpng.so      libpopt.so.0.0.0       libvcongui.so

    其中一些 .a 的静态库是不需要拷过去的,我图方便,一起拷了,呵,懒人的做法

    同时修改 /opt/rootfs/etc/ld.so.conf ,在里面最后新加入一行  /usr/local/lib

    然后执行 [Root] ldconfig –r /opt/rootfs     //把 rootfs 当成根目录,执行

    OK,库文件准备完毕

    下面把资源文件也拷过来,还记得吗,在前面 搭建 PC 环境中讲过安装资源文件,它被装在了 /usr/local/lib 目录下,一个叫 minigui 的目录,我们要做的就是把它拷过来

    [Root]# cp –r –a /usr/local/lib/minigui  /opt/rootfs/usr/local/    连目录一起拷过来,目录结构和主机一样

    把配置文件也拷过来

    [Root]# cp /usr/local/etc/MiniGUI.cfg   /opt/rootfs/usr/local/etc/   记住,保持目录结构的一致

    修改 MiniGUI.cfg ,如下

    [system]
    # GAL engine
    gal_engine=fbcon     //这里修改

    # IAL engine
    ial_engine=dummy      // 这里修改,我不知道你会用什么触摸屏,所以就用dummy肯定不会错

    mdev=/dev/touchscreen/0raw  //解摸屏,如果前面是 dummy ,则这里改不改无所谓
    mtype=none

    [fbcon]
    defaultmode=240x320-16bpp  // 根据你的LCD大小自己设置,设置错误minigui 就启动不了


    ial_engine 一开始建议用 dummy ,先让 minigui 跑起来,以后再把 触摸屏 加进去,保证尽可能减少错误的发生

    保存,退出。 OK ,你的板子上的系统也搭建完毕了,现在来让真正的图形界面跑起来!:)

    注意:你Build 你的 嵌入式 Linux 内核时,在 Console 中一定要先上 FrameBuffer ,从4位色一直到 16 位色的支持,全选上吧,同时把 VGA TextOut 选项勾掉,不要选它!!!!!!!!!!

    内核启动时就要激活 FrameBuffer ,不然 minigui 没法启动起来,激活的方法就是给它传内核参数 vga=xxx 之类的。


    3.启动你的 MiniGUI 的图形界面

    看 看你的 Windows 操作系统,左下方是一个 [开始] 按钮,然后是 任务条 ,MiniGUI 也提供了类似的界面,这就是一个叫 mginit 的程序,它启动后就跟widnows的界面很像了,它就在 mde 包里面,还记得最初让你下载的那个程序包吗??  现在我们就来安装它!!:)

    [user]# tar zxf mde-1.3.0.tar.gz
    [user]# cd mde-1.3.0

    //我们先对 mginit 程序做一点小修改,呵

    [user]#  cd mginit ; vi mginit.c


    在 297 行处,把下面代码注释掉

    /***************
       AboutMiniGUI ();
    AboutMDE ();
    **************/
    保存,退出即可。

    因为我们没有 触摸屏 现在,没法点它的 确认 按钮,所以把这些 About 信息去掉:)

    好了,现在来编译吧,在mde-1.3.0 目录里
    [user]# ./configure --prefix=/opt/rootfs/usr/local --host=arm-linux
    [user]# make

    如果你发现 mginit 目录下的程序没有被编译,那就说明你的 libminigui 配置不正确,记住,你必须是配置为 Lite 模式,这个程序才会被编译


    [user]# make install

    事实上证明,make install,根本没用,它什么都没做,do nothing
    所以还是我们自己动手来做吧,呵

    [Root]# mkdir –p /opt/rootfs/usr/local/lib/shared/miniguiapps    //建立了一个我们自己的目录,好长,呵

    [Root]# cp –r –a  mde-1.3.0/*   /opt/rootfs/usr/local/lib/shared/miniguiapps

    直 接全部拷过去,然后到 /opt/rootfs/usr/local/lib/shared/miniguiapps 的各个程序目录下去,比如 mginit , bomb , painter 之类的,把不用的 .c .h .o Makefile 之类的全删除掉,保留 可执行文件和相应的 res 目录下的资源

    注意,保持目录的结构,mginit.rc 文件不要删了,这个对mginit 程序很重要


    OK,最后一步了,修改配置文件

    [Root]#  vi  /opt/rootfs/linuxrc 文件

    一般你配置嵌入式系统的时候都会有这个文件,用来执行一些系统的初始化工作,如果没有,就在你相应的初始化脚本(例如 etc/inittab)中加入下面的语句

    mknod /dev/ttyp5 c 3 5
    mknod /dev/ptyp5 c 2 5

    cd /usr/local/lib/shared/miniguiapps/mginit
    ./mginit

    注意:最后执行 mginit 命令的方式,先进入到它所在的目录,然后再执行,千万不要只写成

    /usr/local/lib/shared/miniguiapps/mginit/mginit

    因为 mginit 执行时在“当前目录”的res文件夹下搜索显示的资源,这种写法则“当前目录”为 / 根目录,所以会找不到 res 文件夹,于是显示错误
    “ Can not create taskbar! ” 就退出了!

    如果运行时显示没有 mknod 命令,请检查一下你的 busybox 的配置 :)

    切记切记!


    好了,一切成功了,现在放到你的板子上去试试吧:)

    [Root]# cd /opt
    [Root]# mkcramfs  rootfs  root.cramfs  制作根文件系统镜像,把 root.cramfs 烧到你的板子里面就OK了,启动,就可以看到 minigui 的图形界面启动了 :)


    注意: 因为你的 minigui 是按 Lite 模式编译的,如果必须 mginit 首先运行起来,你其它的程序(比如 bomb ,或是 helloword)才能执行,如果 mginit 没有运行起来你就执行 helloword 的话,就会显示错误

    “ Can not attach shared resource ! ”



    4.为  minigui 开发程序


    环境配好了,现在是开发自己的程序了,呵呵,写个简单的 Helloword 程序


    /*
    ** $Id: helloworld.c,v 1.7 2003/06/13 07:15:49 weiym Exp $
    **
    ** Listing 2.1
    **
    ** helloworld.c: Sample program for MiniGUI Programming Guide
    **      The first MiniGUI application.
    **
    ** Copyright (C) 2003 Feynman Software.
    **
    ** License: GPL
    */

    #include <stdio.h>

    #include <minigui/common.h>
    #include <minigui/minigui.h>
    #include <minigui/gdi.h>
    #include <minigui/window.h>

    static int HelloWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
    {
       HDC hdc;
       switch (message) {
           case MSG_PAINT:
               hdc = BeginPaint (hWnd);
               TextOut (hdc, 100, 100, "Hello, world!");
               EndPaint (hWnd, hdc);
               return 0;

           case MSG_CLOSE:
               DestroyMainWindow (hWnd);
               PostQuitMessage (hWnd);
               return 0;
       }

       return DefaultMainWinProc(hWnd, message, wParam, lParam);
    }

    int MiniGUIMain (int argc, const char* argv[])
    {
       MSG Msg;
       HWND hMainWnd;
       MAINWINCREATE CreateInfo;

    #ifdef _LITE_VERSION
       SetDesktopRect(0, 0, 1024, 768);
    #endif

       CreateInfo.dwstyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;
       CreateInfo.dwExstyle = WS_EX_NONE;
       CreateInfo.spCaption = "Hello, world";
       CreateInfo.hMenu = 0;
       CreateInfo.hCursor = GetSystemCursor(0);
       CreateInfo.hIcon = 0;
       CreateInfo.MainWindowProc = HelloWinProc;
       CreateInfo.lx = 0;
       CreateInfo.ty = 0;
       CreateInfo.rx = 320;
       CreateInfo.by = 240;
       CreateInfo.iBkColor = COLOR_lightwhite;
       CreateInfo.dwAddData = 0;
       CreateInfo.hHosting = HWND_DESKTOP;
       
       hMainWnd = CreateMainWindow (&CreateInfo);
       
       if (hMainWnd == HWND_INVALID)
           return -1;

       ShowWindow(hMainWnd, SW_SHOWNORMAL);

       while (GetMessage(&Msg, hMainWnd)) {
           TranslateMessage(&Msg);
           DispatchMessage(&Msg);
       }

       MainWindowThreadCleanup (hMainWnd);

       return 0;
    }

    #ifndef _LITE_VERSION
    #include <minigui/dti.c>
    #endif



    首先在 PC 上编译,验证通过!

    [user]# gcc  -o helloword  helloword.c  -lminigui –lmgext

    如果没有错误,运行 qvfb ,按前面说的设置好,然后执行 [user]# ./helloword

    一切正常,没有错误,现在就要把它放到我们的 板子上去跑了

    [user]# arm-linux-gcc –O2 –o helloword helloword.c –lminigui –lmgext

    编译完后,把它烧到板子的某个目录下,就可以在 板子上跑了!



    所以这里就是说,minigui 提供了让你在 PC 上就可以调试和运行程序的方法(使用qvfb ),等你保证程序正确了以后,只需要把它重新编译一下,放到板子上去就行了!


    5.一些常见的问题

    这几天遇到不一些问题,发现论坛上也基本上没人回答我,所以只好自己解决了,这里把一些问题写出来,方便有需要的人:

    问题1:在板子上跑的程序都显示 can not find qvfb …  之类,可是我只是想让它在板子上跑在 FrameBuffer 之上啊?

    解决:在编译 libminigui 的时候,把
    [ ] Use incore (built-in) resource        //建议不要选这个,老有问题
    [ ]   NEWGAL engine on Qt Virtual FrameBuffer     //建议不要选这个,不然老让你用qvfb


    问题2:编译的时候老出现  unreferenced to vbf_Courier8x8()  之类的问题

    解决:
    [ ] Var bitmap font  //千万不要选这个,不然会出现 unreferenced vfb_Courier8x8() 之类的错误


    问题3:一切都搞定了,可是执行 mginit() 的时候就崩溃了,把所有的寄存器值打印了出来,然后显示了个 Abort() 就退出了!

    解决:
    [ ] IME (GB2312) Intelligent Pinyin module   //千万不要选这个,不然后面你的 mginit 程序一启动就崩溃了


    问题4: 为什么我执行 helloword 就显示 “Can not attach shared resource!”

    解决:
    注意: 因为你的 minigui 是按 Lite 模式编译的,如果必须 mginit 首先运行起来,你其它的程序(比如 bomb ,或是 helloword)才能执行,如果 mginit 没有运行起来你就执行 helloword 的话,就会显示错误

    “ Can not attach shared resource ! ”

    问题5:怎么把自己的程序加到 minigui 的 taskbar 上去,并且排在前面??

    解决:
    查看 mginit 目录下的 mginit.rc 文件,里面就是配置,我想你能看明白的 :)


    问题6:为什么我的程序显示 can not find libminigui.so ??

    解决:你是否忘了在 etc/ld.so.conf 中加入 /usr/local/lib ,并且执行 ldconfig 程序? 看前面说的方法

    好了,就写这么多吧,希望对新手有所帮助!


    Singlewolfyu (大漠孤狼) 写于 清华 FIT 4-305
    2006-11-7
    yuqiang0107@126.com


    把我写的另一篇关于 IAL 校正的文章也归并到这个贴子里来,算是做个汇总吧,原贴可以在论坛中搜 singlewolfyu 的文章就可以找到,原贴里有一些我上传的附件,有兴趣可以去下载,这里就不上传了! 希望这篇文章能对大家有用!

    带屏幕校正功能的 2410 的 IAL
    作者:大漠孤狼                E-MAIL:yuqiang0107@126.com

    前几天成功的把 MiniGUI 移植到板子上了,顺利的跑起来了。我用的是 SMDK2410 的 IAL 程序,可是还有一些问题,如下:

    1:点在触摸屏上不动,可以见到 Cusor 在点的位置附近老是跳动,而且点的位置不准,
    2:经常点 MiniGUI 的菜单或是按钮的时候,MiniGUI 没有反应,经printf 出来,发现菜单有时候收不到 MSG_COMMAND 消息,有时候能收到,就是说很不稳定
    3:经常点击触摸屏的手离开后,Cursor 就消失了

    经过调试后发现了原因,如下:

    1: 由于用的触摸屏是比较便宜的那种,所谓便宜没好货,触摸屏的采样很不稳定,我的屏是 3 寸屏,分辨率是 240x320 16-pp 的那种,可是我点击触摸屏从驱动读出来的值却是 900 多,800 多,而且还不是简单的线性关系,比如我点 X 轴 120 处,值为 400 ,我点X轴 239 处值为 900 ,晕死,如果用原来的 SMDK 2410 IAL 程序,根本无法正常工作

    2:便宜屏还有 个问题,就是在刚开始按触摸屏和快要放手时,这一头一尾两种情况下,采样值根本就是错误的,比如我按在 X 轴 120  处,刚开始得到的值是 230 ,然后是 250,400 ,401,398,403 ……402,100,101 ,这样的序号,可以看到,在刚开始和快结束时采到的值根本是错误的,这就是为什么我说“手一离开触摸屏,Cusor就消失”的原因为了,因为这时候 Cusor 跑到错误的坐标值上去了,当然就消失了

    3:经常点 MiniGUI 的菜单却没有响应,其实还是上面 2 的原因,菜单的响应是当你的手离开触摸屏后,会产生一个 MSG_LBUTTONUP 消息,在这个消息中会调用 PtInRect()检查这时候的点击位置是否在菜单上,如果在的话,菜单就会触发一个 MSG_COMMAND 消息,于时菜单就会显示出来,其实 MiniGUI 中对所有的点击都是这样处理的。(自己看看 MiniGUI 的源代码就会明白了)。因为我的便宜屏在手快要离开触摸屏时得到的坐标是错误的,所以这时候 PtInRect() 就会返回错误的值,就好像我点在屏的别的地方了一样,所以这时候菜单根本得不到消息。


    根据以上原因,我对 MiniGUI  1.3.3 版本中的 2410 的 IAL 程序进行了修改,使得它在我的 便宜屏 上一样可以正常工作。它提供了去抖动功能,就是点击时一头一尾那两下的不准确的值不能要,同时提供了一个方便的屏幕校准程序,你只需要做小小的修改就可以 校准让它在你的 便宜屏 上很好的正常工作了。

    新程序的使用方法:

    在 2410.c 中定义了两个数组,如下


    typedef struct mPoint {      int      x,
                                   y ;
                       } mPOINT ;

    static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940} };
    static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0} };

    ts_position 意思为 TouchScreen 的 位置
    display_position 意思为屏幕上显示的 位置

    比如我前面说的,我的屏幕是 240x320 的,我点四个角 {0,0},{0,319},{239,319},{239,0} ,从触屏上读出来的数据分别为 {940,926},{940,102},{96,104},{120,940} ,填入这两个数就行

    所以使用方法就是,你自己取四个点(其实只要3个点就够了,呵),点这四个点,得到相应的触摸屏读出来的值,把这些数据填到这两个数组中,OK,你的 触摸屏 就可以正常工作了 :)

    后面附一个 readpos.c  的程序,你可以执行它,然后点击触摸屏,它会显示出触摸屏读出来的值。

    程序: 2410_带触摸屏校正功能.c

    /*
    ** $Id: 2410.c,v 1.4 2003/11/21 12:15:37 weiym Exp $
    **
    ** 2410.c: Low Level Input Engine for SMDK2410 Dev Board.
    **
    ** Copyright (C) 2003 Feynman Software.
    */

    /*
    ** This program is free software; you can redistribute it and/or modify
    ** it under the terms of the GNU General Public License as published by
    ** the Free Software Foundation; either version 2 of the License, or
    ** (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU General Public License for more details.
    **
    ** You should have received a copy of the GNU General Public License
    ** along with this program; if not, write to the Free Software
    ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>

    #include "common.h"

    #ifdef _SMDK2410_IAL

    #include <sys/ioctl.h>
    #include <sys/poll.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <linux/kd.h>

    #include <sys/time.h>  /* i add it here */
    #include <math.h>
    #include <sys/poll.h>
    #include <sys/types.h>

    #include "ial.h"
    #include "2410.h"

    typedef struct mPoint {
                          int      x,
                                   y ;
                       } mPOINT ;

    static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940}

                                 };
    static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0}
                                    };

    typedef struct Matrix {
    /* This arrangement of values facilitates
    *  calculations within getDisplayPoint()
    */
                          int      An,     /* A = An/Divider */
                                   Bn,     /* B = Bn/Divider */
                                   Cn,     /* C = Cn/Divider */
                                   Dn,     /* D = Dn/Divider */
                                   En,     /* E = En/Divider */
                                   Fn,     /* F = Fn/Divider */
                                   Divider ;
                       } mMATRIX ;

    static mMATRIX m_matrix;

    int setCalibrationMatrix( mPOINT * display,
                                   mPOINT * screen,
                                   mMATRIX * matrix) ;


    int getDisplayPoint( mPOINT * display,
                              mPOINT * screen,
                              mMATRIX * matrix ) ;



    /* for data reading from /dev/ts */
    typedef struct {
      unsigned short pressure;
      unsigned short x;
      unsigned short y;
      unsigned short pad;
    } TS_EVENT;

    static unsigned char state [NR_KEYS];
    static int ts = -1;
    static int mousex = 0;
    static int mousey = 0;
    static TS_EVENT ts_event;


    #undef _DEBUG

    /************************  Low Level Input Operations **********************/
    /*
    * Mouse operations -- Event
    */
    static int mouse_update(void)
    {
      return 1;
    }

    static void mouse_getxy(int *x, int* y)
    {
    #ifdef _DEBUG
      printf ("mousex = %d, mousey = %d\n", mousex, mousey);
    #endif

      if (mousex < 0) mousex = 0;
      if (mousey < 0) mousey = 0;
      if (mousex > 239) mousex = 239;
      if (mousey > 319) mousey = 319;

      *x = mousex;
      *y = mousey;
    }

    static int mouse_getbutton(void)
    {
     return ts_event.pressure;
    }

    #ifdef _LITE_VERSION
    static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,
                  struct timeval *timeout)
    #else
    static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,
                  struct timeval *timeout)
    #endif
    {
      fd_set rfds;
      int    retvalue = 0;

      int    e;

    static int last_pressure=0;

      if (!in) {
          in = &rfds;
          FD_ZERO (in);
      }

      if ((which & IAL_MOUSEEVENT) && ts >= 0) {
          FD_SET (ts, in);
    #ifdef _LITE_VERSION
          if (ts > maxfd) maxfd = ts;
    #endif
      }


    #ifdef _LITE_VERSION
      e = select (maxfd + 1, in, out, except, timeout) ;
    #else
      e = select (FD_SETSIZE, in, out, except, timeout) ;
    #endif


      if (e > 0) {
          if (ts >= 0  && FD_ISSET (ts, in) ) {
              FD_CLR (ts, in);
              ts_event.x=0;
              ts_event.y=0;

              read (ts, &ts_event, sizeof (TS_EVENT));  

             if(last_pressure==0)
             {
                read(ts,&ts_event,sizeof(TS_EVENT));
                read(ts,&ts_event,sizeof(TS_EVENT));
     }
             
              if (ts_event.pressure > 0 ) {
           
                  int new_x;
                  int new_y;

    mPOINT ts_point,display_point;
                 
                  ts_point.x=ts_event.x;
                  ts_point.y=ts_event.y;
                   
                  getDisplayPoint(&display_point,&ts_point,&m_matrix);
                   

                  new_x = display_point.x;
                  new_y = display_point.y;
                 
    if(last_pressure==0 || (last_pressure>0 && abs(new_x-mousex)<7))
                          mousex=new_x;
                  if(last_pressure==0 || (last_pressure>0 && abs(new_y-mousey)<7))
                          mousey=new_y;
    /*
    printf("ts_x=%d,ts_y=%d\n",ts_event.x,ts_event.y);              
    printf("mounsex=%dmousey=%d\n",mousex,mousey);
    */
              }

    #ifdef _DEBUG
              if (ts_event.pressure > 0) {
                  printf ("mouse down: ts_event.x = %d, ts_event.y = %d\n", ts_event.x, ts_event.y);
              }
    #endif
             
              ts_event.pressure = ( ts_event.pressure > 0 ? IAL_MOUSE_LEFTBUTTON : 0);
                 
      last_pressure=ts_event.pressure;
    /*    
    printf("pressure=%d\n",ts_event.pressure);
    */
              retvalue |= IAL_MOUSEEVENT;
          }

      }
      else if (e < 0) {
          return -1;
      }

      return retvalue;
    }

    BOOL Init2410Input (INPUT* input, const char* mdev, const char* mtype)
    {
      ts = open ("/dev/ts", O_RDONLY);
      if (ts < 0) {
          fprintf (stderr, "2410: Can not open touch screen!\n");
          return FALSE;
      }



      input->update_mouse = mouse_update;
      input->get_mouse_xy = mouse_getxy;
      input->set_mouse_xy = NULL;
      input->get_mouse_button = mouse_getbutton;
      input->set_mouse_range = NULL;

      input->wait_event = wait_event;
      mousex = 0;
      mousey = 0;
      ts_event.x = ts_event.y = ts_event.pressure = 0;

    setCalibrationMatrix(&display_position,&ts_position,&m_matrix);    
      return TRUE;
    }

    void Term2410Input(void)
    {
      if (ts >= 0)
          close(ts);    
    }

    #endif /* _SMDK2410_IAL */

    int setCalibrationMatrix( mPOINT * displayPtr,
                            mPOINT * screenPtr,
                            mMATRIX * matrixPtr)
    {

      int  retvalue = 0 ;


     
      matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
                           ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

      if( matrixPtr->Divider == 0 )
      {
          retvalue = -1 ;
      }
      else
      {
          matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
                          ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

          matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
                          ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;

          matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
                          (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
                          (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;

          matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
                          ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
     
          matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
                          ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;

          matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
                          (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
                          (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
      }

      return( retvalue ) ;

    } /* end of setCalibrationMatrix() */

    int getDisplayPoint( mPOINT * displayPtr,
                       mPOINT * screenPtr,
                       mMATRIX * matrixPtr )
    {
      int  retvalue = 0 ;


      if( matrixPtr->Divider != 0 )
      {

              /* Operation order is important since we are doing integer */
              /*  math. Make sure you add all terms together before      */
              /*  dividing, so that the remainder is not rounded off     */
              /*  prematurely.                                           */

          displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
                            (matrixPtr->Bn * screenPtr->y) +
                             matrixPtr->Cn
                          ) / matrixPtr->Divider ;

          displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
                            (matrixPtr->En * screenPtr->y) +
                             matrixPtr->Fn
                          ) / matrixPtr->Divider ;
      }
      else
      {
          retvalue = -1 ;
      }

      return( retvalue ) ;

    } /* end of getDisplayPoint() */



    Readpos.c 程序,帮助你读取触摸屏的值


    #include <stdio.h>

    typedef struct {
      unsigned short pressure;
      unsigned short x;
      unsigned short y;
      unsigned short pad;
    } TS_EVENT;

    static TS_EVENT ts_event;
    static int ts;

    int main()
    {
      ts = open ("/dev/ts", 0);
      if (ts < 0) {
          fprintf (stderr, "2410: Can not open touch screen!\n");
          return 0;
      }

    while(1)  
    {
          if(       read (ts, &ts_event, sizeof (TS_EVENT)))
         {
             printf("X=%d,Y=%d,Pressure=%d \n",ts_event.x,ts_event.y,ts_event.pressure);
          }      

    }

    }


    大漠孤狼   yuqiang0107@126.com
    2006-11-11  写于 清华 FIT 4-305



  • MiniGUI 1.3.3 移植详解


    MiniGUI 1.3.3 移植详解

    作者:大漠孤狼  

    最近移植了 MiniGUI 1.3.3 到一个开发板上,中间遇到许多问题,在论坛上发问 题,结果也没多少人回我,就算偶尔有回的,基本上回答也没有什么用,网上找不到一个完整的移植文章,所以就决定把自己这次移植摸出来的一些方法写出来,给 像我一样的小菜鸟做个参考吧。本文不教你怎么写驱动,只是教怎么样在最短的时候在你的PC机上搭建起开发环境,同时在你的板子上跑起MiniGUI 来, 这样你就可以在PC上开发好程序,调试完毕,然后http://www.minigui.com/download/libminigui-1.3.3.tar.gz    

    http://www.minigui.com/download/minigui-res-1.3.3.tar.gz       

    这两个包的下载需要你在www.minigui.com  上注册过才可以下载,免费注册的,自己去下吧

    http://www.minigui.com/downloads/minigui13/mde-1.3.0.tar.gz    图形界面程序

    http://www.minigui.com/downloads/minigui13/mg-samples-1.3.0.tar.gz  一些小例子

    好,首先就下载这几个包吧,后面还有需要下载的包,后面再说

    1.PC环境的搭建

    首先你需要一个 http://www.minigui.com/downloads/dep-libs/qvfb-1.0.tar.gz 

    老方法:

    [user]# tar zxf qvfb-1.0.tar.gz

    [user]# cd qvfb-1.0

    [user]# ./configure

    [user]# make

    [user]# make install

    在这个过程中如果出现 error while loading shared libraries: libqt-mt.so.3: cannot open shared object file

    说明你的系统少了 libqt-mt.so.3 这个库,还是回去检查一下,你安装时 Redhat 时是否选了 everything ,或者在实际操作的过程中,这个库有可以被误删除掉,我就出现过,这时候你可以 google 一下  ,输入 libqt-mt.so.3 redhat 9 ,应该就可以搜到相应的 rpm 包,安装时

    [root]# rpm –i --force [你的包名]   OK  

    这里有个下载地址,可以试试,我是用讯雷下载的,别的工具没试过

    ftp://ftp.pbone.net/mirror/www-ccrma.stanford.edu/planetccrma/mirror/redhat/linux/planetccrma/9/en/os/i386/qt33-3.3.3-0.1.rh90.ccrma.i386.rpm 

    注意:在你后面的操作过程中有可能会导致 libqt-mt.so.3 丢失,这时候只要重装一下就OK

    解决了这个问题后重复安装过程

    [user]# ./configure

    [user]# make

    [user]# make install

    OK ,环境搭建好了,下面是测试了:)

    还记得前面让你下载的 mg-samples-1.3.0.tar.gz 这个包吧,这个就是一些例子,现在试试吧:)

    [user]# tar zxf mg-samples-1.3.0.tar.gz

    [user]# ./configure

    [user]# make

    [user]# cd src

    看看 src 目录下是不是已经编译出可执行文件来了

    现在来执行一下吧,首先把 qvfb 加到你的可执行路径中去

    [user]# cd $HOME

    [user]# vi .bashrc

     .bashrc 最后面加上一句

    export PATH="$PATH:/sbin:/usr/local/ftp://ftp.arm.linux.org.uk/pub/linux/arm/toolchain/cross-2.95.3.tar.bz2 

    记住这个 ftp ,最好的 arm 工具下载站,

    下载回来,有35Mb,呵

    安装交叉编译工具:

    [Root]# mkdir  –p  /usr/local/arm

    [Root]# cd /usr/local/arm

    [Root]# tar jxf  cross-2.95.3.tar.bz2   //把工具直接解到压缩到这个目录下就安装完成了,简单吧:)

    解压缩后生成一个 2.95.3 目录,里面在就是工具

    记住,这时候的gcc 2.95.3/bin/arm-linux-gcc   而它的 include  2.95.3/arm-linux/include ,对应的 lib  2.95.3/arm-linux/lib

    也就是说,你如果用 arm-linux-gcc 编译程序的话,它缺省的就找 2.95.3/arm-linux/include   2.95.3/arm-linux/lib  两个目录,而不是 /usr/include ,所以如果你要加什么 .h  .a .so 文件话,记着一定是加到这两个目录下去,不然编译器会告诉你找不到这些东西的

    把可行程序的路径加入到 PATH 中去,还记得前面说过的改 .bashrc 文件吗?

    [user]# cd $HOME

    [user]# vi .bashrc

     .bashrc 最后面加上一句

    export PATH="$PATH:/sbin:/usr/local/arm/2.95.3/bin:/usr/local/bin:/usr/local"   

    [user]# source .bashrc

    OK 交叉编译工具安装完了,够简单吧:)

    MiniGUI 的编译需要一些库文件,缺省我们的 gcc 基本上都有这些库文件,所以不需要安装,可是现在要交叉编译了,交叉编译器可是不带这些库文件的,所以我们得首先自己编译这些库文件装到交叉编译器中去。

    注意一点:库不一定要装最新的,库版本太新,MiniGUI 有可能不认识,像jpeg 库和 ttf 库就是这样,太新了反而用不了,所以要注意版本,以下的库都是我验证过可以和MiniGUI一起工作的,其它版本的库没试过,不保证能正确通过:)

    首先安装 zlib 库,这个是后面的库的编译基础。

    http://www.zlib.net/zlib-1.2.3.tar.gz  400K,去下载吧,

    下载到目录 /opt/st2410 

    [user]# tar zxf zlib-1.2.3.tar.gz

    由于 zlib 库的configure 脚本不支持交叉编译选项,只好自己动用了,手动临时把 gcc 修改成指向我们的交叉编译 arm-linux-gcc

    [Root]# cd /usr/bin

    [Root]# mv gcc gcc_back

    [Root]# ln -s /usr/local/arm/2.95.3/bin/arm-linux-gcc ./gcc

    [Root]# mv ld ld_back

    [Root]# ln -s /usr/local/arm/2.95.3/bin/arm-linux-ld ./ld

    OK ,修改完成后回到 /opt/st2410/zlib-1.2.3 目录下

    [user]#  ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --shared  

    注意:这里配置指向 /usr/local/arm/2.95.3/arm-linux目录,会自动安装在 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录下,千万不要装错目录了,不然后面会找不到这个库的

    [user]#  make

    [Root]# make install

    安装完后检查一下目录 /usr/local/arm/2.95.3/arm-linux/  [include,lib] ,假如 include 中没有 zlib.h 之类的头文件,lib 中没有 libz.so.1.2.3 ,那就自己手 动拷到这些目录下去,记着拷的时候把所有的 *.h  都需要拷过去,在拷库的时候用 cp –a libz.* /…./lib  就行,要用上  –a 选项

    记着把刚才改过的 gcc 再改回去,不然后面会出错的!!!!!

    安装 png 库,这个是用来显示 png 图形的,MiniGUI 里很多图都是 png 的,如果没有这个库,你的 MiniGUI 将无法正常工作,切记切记!

    http://superb-east.dl.sourceforge.net/sourceforge/libpng/libpng-1.0.10rc1.tar.gz 

    还是那句话,库不要用最新的,最新的容易有问题,用这个老一点的就没问题了,呵

    [user]# tar zxf libpng-1.0.10rc1.tar.gz

    [user]# cd libpng-1.0.10rc1

    Libpng 不提供有效的 configure 脚本,所以只好自己动手改 Makefile 文件了

    [user]# cp scripts/makefile.linux  Makefile   // Scripts  下的一个 makefile 拷出来自己动手改

    [user]# vi Makefile    // 自己动手改

    CC=arm-linux-gcc    //修改这里

    # where "make install" puts libpng.a, libpng.so*, png.h and pngconf.h

    prefix=/usr/local/arm/2.95.3/arm-linux     //修改这里

    # Where the zlib library and include files are located

    #ZLIBLIB=/usr/local/lib

    #ZLIBINC=/usr/local/include

    ZLIBLIB=/usr/local/arm/2.95.3/arm-linux/lib   //修改这里

    ZLIBINC=/usr/local/arm/2.95.3/arm-linux/include   //修改这里

    好了,保存,然后去编译吧

    [user]#  make

    [user]#  make install 

    如果有错误,检查你前面的步骤哪个没做对 :) 尤其是 zlib 的安装

    还是前面说的,检查 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录中有成功安装否,如果没有安装成功,那就自己把编译出来的东西拷过去。记着,*.h  .so 的文件都要拷。

    OK,现在来安装 jpeg 

    ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz    自己去下载,速度暴慢

    [user]# tar zxf jpegsrc.v6b.tar.gz

    [user]# cd jpeg-6b

    [user]# ./configure –help    //可以查看它的配置选项

    一般情况下用 [cdp@cdpserver jpeg-6b]$ ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --host=arm-linux --enable-shared --enable-static

    --host=arm-linux  来指定交叉编译选项,可是这里死活它不认,所以改用别的方法,如下

    [user]# ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ CC=arm-linux-gcc --enable-shared --enable-static

    [user]# make

    安装前需要在 arm-linux 下建个目录,不然安装会出错

    [Root]# mkdir –p /usr/local/arm/2.95.3/arm-linux/man/man1

    [Root]# make install    // OK 

    一样,自己去检查一下安装是否成功 :)

    最后安装 libttf 库,这个是 TrueType 字体的支持库,用来显示文字的。

    http://nchc.dl.sourceforge.net/sourceforge/freetype/freetype-1.3.1.tar.gz 

    注意:MiniGUI 的文档说只支持 1.3.1 版本的 ttf 库不要把版本弄错了 :),

    这个库装起来最麻烦,全部自己手动编译,安装,下面一步一步来做吧:)

    [user]# tar zxf  freetype-1.3.1.tar.gz       //老一套

    [user]# cd freetype-1.3.1   //进到目录里去

    [user]# mkdir –p /opt/st2410/libttf/extend   // 自己另外建立一个目录

    [user]# cp freetype-1.3.1/lib/*  freetype-1.3.1/lib/arch/ansi/*  libttf/   //把有用的东西拷出来

    [user]#cp freetype-1.3.1/lib/extend/*  libttf/extend/     extend 目录下的文件也拷出来

    注意 cp 命令不要用 –r 选项,因为会把一些没用的东西出拷出来的

    拷贝完成了,现在来自己手动编译了

    [user]# cd libttf

    [user]# arm-linux-gcc -c -fPIC -O2 freetype.c         //不要奇怪,对,我们只要编译这一个 .c 文件,因为它包括了其它所有的 .c 文件了,你可以自己查看它的内容  

    [user]# arm-linux-gcc -c -fPIC -O2 -I./  extend/*.c    extend 下所有的 .c 文件全部编译

    [user]# arm-linux-gcc --shared -o libttf.so *.o    生成最后的动态链接库,OK

    现在手动安装,得自己建立一下目录

    [Root] mkdir –p /usr/local/arm/2.95.3/arm-linux/include/freetype1/freetype

    [Root] cp *.h  extend/*.h   /usr/local/arm/2.95.3/arm-linux/include/freetype1/freetype

    [Root] cp libttf.so  /usr/local/arm/2.95.3/arm-linux/lib

    安装库完成,哈!

    经过试验发现 MiniGUI 1.3.3 版本在链接 ljpeg lpng lttf 时老是要链接 /usr/lib 下的库,没办法,用老方法

    [Root]# cd /usr/lib

    [Root]# mv libjpeg.so   libjpeg.so_back

    [Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libjpeg.so  ./libjpeg.so    //指向 arm 的库

    [Root]# mv libpng.so   libpng.so_back

    [Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libpng.so  ./libpng.so

    [Root]# mv libttf.so   libttf.so_back

    [Root]# ln –s /usr/local/arm/2.95.3/arm-linux/lib/libttf.so  ./libttf.so

    完成以上工作后就可以编译 libminigui 

    [user]# cd libminigui-1.3.3

    [user]#  make menuconfig                //就用图形界面来配置就好了,不要用一堆 –enable-xxx 之类的,太麻烦

    如果在 make menuconfig 出错,去检查一下你的 gcc ,前面我们把它指向 arm-linux-gcc ,问一下,你改回来没有???????

    下面是配置libminigui 

     System Wide Options 里如下:

    ·   Build MiniGUI-Lite        // Lite 方式编译,不是Thread 方式,这里适用于 PDA

    [ ]   Stand-Alone

    [ ] Use incore (built-in) resource        //建议不要选这个,老有问题

    ·   Unit of timer is 10ms

    ·   Cursor support

    [ ] User can move window with mouse   //建议别选这个,可以移动蛮烦人的

    ·   Mouse button can do double click

    ·   Build with debugging messages

    [ ] Trace messages of MiniGUI        //不要选这个,出来的Trace太多,看不过来

    ·   Include symbol name of messages

     GAL  engine Options 

    (NEWGAL) GAL and its engines

    ·     NEWGAL engine on Linux FrameBuffer console

    [ ]   NEWGAL engine on Qt Virtual FrameBuffer     //建议不要选这个,不然老让你用qvfb

    [ ]   NEWGAL engine on eCos LCD interface

    ·     Dummy NEWGAL engine

    ·   Have console on Linux FrameBuffer

     IAL engine options 

    [ ] EP7211-based board

    [ ] ADS Graphics Client

    [ ] iPAQ H3600 (also H3800)

    [ ] MPC823

    [ ] PX255B

    [ ] NEC VR4181

    [ ] Helio Touch Panel

    [ ] MT T800

    ·   SMDK2410 Touch Screen

    [ ] uClinux Touch Screen Palm/MC68EZ328

    ·   Dummy IAL engine

    ·   Native (console) input engine

    ---   Native IAL engine subdriver options

    [ ]   PS2 mouse

    [ ]   IntelligentMouse (IMPS/2) mouse

    [ ]   MS mouse

    [ ]   MS3 mouse

    ·     GPM daemon

     Font Option 

    ·   Raw bitmap font

    [ ] Var bitmap font  //千万不要选这个,不然会出现 unreferenced vfb_Courier8x8() 之类的错误

    ·   Incore font sansserif

    ·   Incore font courier

    ·   Incore font symbol

    ·   Incore font vgas

    ·   Qt Prerendered Font

    ·   TrueType font

    [ ] Adobe Type1 font

     Image Options 

    ·   Includes SaveBitmap-related functions

    [ ] PCX file support

    [ ] LBM/PBM file support

    [ ] TGA file support

    ·   GIF file support

    ·   JPG file support

    ·   PNG file support

     Input Medthold Option 

    ·   IME (GB2312) support

    [ ] IME (GB2312) Intelligent Pinyin module   //千万不要选这个,不然后面你的 mginit 程序一启动就崩溃了(Abort ,有点像 OOP 一样,显示所有的寄存器的值,然后Abort),暴不爽

     Development Environment Option 

    (Linux) Platform

    (arm-linux-gcc) Compiler   //注意这里

    (glibc) Libc             //注意这里

    --- Installation options

    Path prefix: "/usr/local/arm/2.95.3/arm-linux"   //注意这里,我们把库装到交叉编译器的目录下

    --- Additonal Compiler Flags

         CFLAGS: ""

         LDFLAGS: ""

    其它的用缺省的选项就可以了,好了,现在退出,保存你的设置吧,然后它就开始检测你的系统了,注意下面的输出:

    checking for FrameBuffer console support... yes

    checking for TT_FreeType_Version in -lttf... yes      //True Type字体

    checking for jpeg_std_error in -ljpeg... yes           // jpeg 支持

    checking for png_check_sig in -lpng... yes           //png 图形支持,重要!!!

    checking for pow in -lm... yes

    这里的库应该都是显示为 yes 了,如果有 no 的话,回去检查前面你有哪步做得不对,不然的话编译后的东西可能没法正常执行,切记切记!!!

    如果这里通过了,那就OK

    [user]#  make  //又是一个漫长的等待,呵

    [Root]#  make install

    注意:我们这里 make install 其实是给交叉编译器安装 libminigui 的库,你想,将来你需要编译为 minigui 开发的程序,这个程序总是需要链接库的吧,这些库因此也需要在交叉编译器中,不然你交叉编译的时候编译不过去 :)

    装好了,到 /usr/local/arm/2.95.3/arm-linux   include lib 目录下去看看,是不是多了相应的 libminigui.so  libmgext.so  libvcongui.so     include 目录下多了一个 minigui 目录,里面有相应的头文件