移植MINIGUI最經典文章

 轉載來自MINIGUI論壇,經常查閱,所以轉過來我空間,大家要看還是上MINIGUI論壇,我只是放我空間便於查閱。

MiniGUI 1.3.3 移植詳解

作者:大漠孤狼   E-Mail:[email protected]

最近移植了 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
[email protected]


把我寫的另一篇關於 IAL 校正的文章也歸併到這個貼子裏來,算是做個彙總吧,原貼可以在論壇中搜 singlewolfyu 的文章就可以找到,原貼裏有一些我上傳的附件,有興趣可以去下載,這裏就不上傳了! 希望這篇文章能對大家有用!

帶屏幕校正功能的 2410 的 IAL
作者:大漠孤狼                E-MAIL:[email protected]

前幾天成功的把 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);
      }      

}

}

發佈了16 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章