DirectFB移植(GUI arm linux DirectFB GTK tslib)

DirectFB移植

1 前言
      數年前,曾經開發過一個嵌入式的產品,如今市場依然存在,但由於電子產品的升級換代很快,許多元器件都採購不到了,爲了延續產品的生命週期,計劃在linux平臺上開發新的版本。而在linux上的GUI上成了大問題,最開始有用Minigui的打算,也同飛漫公司聯繫過,但費用我這裏無法承受。(Minigui作爲國產優秀的嵌入式GUI,如果不是費用的問題,應該是最優的選擇。) QT我也看了下,也是收費的,沒有仔細研究。最開始我打算用MicroWindow的,但後來發現這個東西好久沒有更新了,bug一大堆。最後的目光停留在GTK上,最開始無從下手,不知道到底適合不適合做嵌入式GUI,最後不知道在哪裏看到一個介紹說諾基亞有產品是用GTK的,覺得既然別人能做得,我也能做得。最開始做這個,相關資料太少,一點底都沒有,但經過兩個月(長了點)的努力,終於解決了所有問題,才一顆石頭落地。個人認爲,在本文的幫助下,如果你擁有初中級的嵌入式linux的知識,也許一天就能解決問題,最長也不會超過一個星期。
2 準備工作
硬件環境:linux主機一臺,如果你喜歡用windows,可以在windows主機上用vmware虛擬一個linux系統。嵌入式開發套件,包括嵌入式開發板、帶觸屏的液晶屏及相關連接電纜。
軟件環境:x86 linux發行版,配置好framebuffer,並安裝好ftp server、telnet server、tftp server、nfs server、gcc及相關軟件、交叉編譯器、開發套件的kernel 2.6的源碼包。
    本人用的是Ubuntu 7.10的發行版,嵌入式開發版採用三星的2440系列cpu,如何搭建開發環境不在本文討論範圍之類,請參考其他文檔。交叉編譯器用的是自己編譯的3.4.1,最開始採用的是開發套件帶的3.4.1,爲什麼要用自己編譯的而不用開發套件自帶的呢? 這裏說本文第一個祕笈:由於GTK採用的矢量字體裏一些算法使用了浮點運算,而24xx系列的cpu硬浮點不支持(我沒有相關知識,這是我的一個同事說得,是不是他本來意思,我都不敢確定,如果你的cpu不是這個系列的,請查看相關資料),只要在交叉編譯器里加上軟浮點運算支持,就應該沒有問題了,所以在開始之前,先檢查交叉編譯器裏有沒有--with-float=soft這個選項。在我使用開發版自帶的編譯完成編譯後,運行gtk的程序,總是有這個提示” shape engine failure, expect ugly output. the offending font is”,而屏幕上所有字符都顯示不出來,button由於字符無法顯示,被壓縮成一條線,這個問題困擾我好幾天,我開始以爲是字庫設置的問題,後來求助同事,他聽了我的描述後,猜測可能是浮點運算的問題,讓我用我們自己編譯的交叉編譯器重新編譯一下,看看能不能解決問題,結果真的解決了。
3 源碼包的選擇
     選用GTK做嵌入式GUI是個痛苦的選擇,如果選用商業GUI如MiniGui,別人都給你整好了,你拿過來用就可以了,或者用Wince,還是與windows兼容的。而選用GTK做GUI,不同組織(個人)編寫的15個軟件包,各個軟件包又有不同的版本,而網上又沒有權威的指南,如何選擇合適的版本以及如何整合確實是個非常複雜的問題。
我是先從在x86上搭建GTK環境開始的,首先我選用最新版本,然後,看到介紹說,GTK在framebuffer上運行有兩種模式: DirectFB 和linux-fb,而linux-fb的項目好像已經停止,主要方向是DirectFB,後來查的有個DirectFB + GTK的英文文檔,基本都選用最新的版本,而且很多包都可以使用系統自帶的,編譯必須的源碼就可以了,最開始怎麼也編譯不成功,我快絕望的時候,發現釋放出一個最新的GTK源碼版本(大概是08年7月4日),我第一時間下載下來,很快就編譯出來了,並且在framebuffer模式下gtk-demo以及一些test運行一點問題都沒有。
      熟悉了編譯過程後,我先嚐試用交叉編譯這個最新版本,編譯第一個包glib-2.16.4就失敗了。我在網上閱讀了很多關於交叉編譯DirectFB+GTK的的資料,有個用shell腳本寫的好像不錯,但是看不懂呀,雖然我接觸unix都十多年了,還曾經在unix下做個一比較大型的項目,但後來,linux都是個人興趣,看了一些,玩了一些,沒做過東西,shell編程看過,好多東西一直半解,他那篇文檔看的我都傻了,這人真牛。但源碼包的選擇是可以借鑑的。
我的選擇:
1) tslib-1.0.tar.bz2
     觸摸屏本來我是最後弄的,但如果你需要觸屏支持,最好在一開始就搞定他。這個其實是tslib.14,爲啥成了1.0的了,我也不知道,如何編譯不是很難,難在怎麼配置,相關文檔請閱讀本人的另外一篇文檔《arm-linux之tslib》,當然哪片文檔可能並不能幫你搞定,你需要動用你的聰明才智,你也許需要閱讀kernel裏觸屏驅動的源碼。我的開發套件觸屏控制器是用的cpu本身的AD轉換器,kernel裏的驅動是兼容H3600的,所以我在ts.conf文件裏module_raw模塊設置爲h3600。如果你用的三星的24XX系列的cpu,也許使用的方式跟我相同,使用同樣的配置也許可以,如果不行,可能要閱讀觸屏驅動的源碼及tslib的module_raw的源碼,找到匹配的模塊就行了。
《arm-linux之tslib》的位置http://www.directfb.com.cn/viewthread.php?tid=388&extra=page%3D12) freetype-2.3.5.tar.bz2
3) glib-2.12.13.tar.bz2

4) libpng-1.2.19.tar.bz2
    這個模塊本來我是不需要的,我在編譯GTK的時候想disable這個模塊,configure無法完成。
5) zlib-1.2.3.tar.bz2
6) jpegsrc.v6b.tar.gz

    這個模塊是我必須的,但編譯GTK的時候,configure說找不到這個模塊的jpeglib.h,我也研究了好久,
7) tiff-3.7.4.tar.gz
這個模塊我不需要,但編譯了,最終,我不會採用這個模塊。
8) DirectFB-1.1.1.tar.gz
    最開始我採用的是1.1.0,基本正常,最後弄觸屏的時候,運行程序DirectFB怎麼也加載不成功nputdrivers裏的模塊libdirectfb_tslib.so,閱讀了相關代碼後,發現這個版本的DFB的這個模塊加載後,不讀取tslib的相關環境變量,直接加載/dev/input/tslibn些設備,而我的開發板起來後,根本沒有這些設備,1.1.0之後的版本,相關代碼做過修正,我也嘗試了最新版本的DFB 1.2.1,但這個版本的DF B跟好核後面選用的GTK的版本配合有點問題,無法編譯後面的GTK,我閱讀DFB 1.1.1的相關代碼,發現已經修正,選用了這個版本,運行GTK程序,DFB開始加載tslib的相關模塊,但只加載成功tslib的module_raw的模塊,後面的模塊加載失敗。什麼原因這裏不做解釋,後面再說。
9) atk-1.19.3.tar.bz2
10) expat-2.0.1.tar.gz

11) libxml2-2.6.29.tar.gz
12) fontconfig-2.4.2.tar.gz
13) pango-1.16.4.tar.bz2
14) cairo-1.4.10.tar.gz
15) gtk+-2.10.14.tar.bz2

    這個模塊最後編譯,編譯完成意味着我們成功完成了編譯工作,我configure這個模塊的時候碰到了兩個問題:第一找不到pango,最後看到好多,才知道在configure前需要設置這個環境變量export LDFLAGS="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib" 這個啥意思,我不知道,爲什麼這樣設我也不知道。第二找不到jpeglib.h,我分析了log,發現是在測試g++編譯的時候,找不到jpeglib.h,而測試gcc編譯是沒有問題的,我在configure前設置了這個export CPPFLAGS="-I$PREFIX/include"環境變量,告訴g++編譯器到哪裏找jpeglib.h。
4 交叉編譯
    在宿主系統上交叉編譯後的所有包的安裝目錄爲/usr/gtkdfb,當然,你可以使用其他的目錄,但絕不能跟主機環境相沖突,將交叉編譯後東西安裝到宿主系統的默認位置,可能會導致你的宿主系統某些不可預知的後果。下面開始編譯
1) Tslib
export PREFIX=/usr/gtkdfb
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --prefix=$PREFIX -

-cache-file=arm-linux.cache --enable-inputapi=no
make
make install

編譯前只需要指定PREFIX一個環境變量,這個模塊編譯下面的編譯基本都需要以下三個
export LDFLAGS=-L$PREFIX/lib
export CFLAGS="-g -I$PREFIX/include"
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig

2) glib
echo ac_cv_type_long_long=yes>arm-linux.cache
echo glib_cv_stack_grows=no>>arm-linux.cache
echo glib_cv_uscore=no>>arm-linux.cache
echo ac_cv_func_posix_getpwuid_r=yes>>arm-linux.cache
CC=arm-linux-gcc ./configure --host=arm-linux --build=i686-pc-linux --prefix=$PREFIX --cache-file=arm-linux.cache
make
make install

3) atk
./configure --host=arm-linux --prefix=$PREFIX
make
make install
4) jpeg-6b
./configure  --prefix=$PREFIX --enable-shared --enable-static
修改生成的Makefile文件:
       # The name of your C compiler:
       CC= gcc  該成  CC=arm-linux-gcc (根據你自己交叉編譯器的位置修改)
       # library (.a) file creation command
       AR= ar rc 該成  AR= arm-linux-ar rc  (同上)
       # second step in .a creation (use "touch" if not needed)
       AR2= ranlib 該成  AR2=arm-linux-ranlib (同上)
mkdir $PREFIX/man
mkdir $PREFIX/man/man1

make
make install-lib

5) zlib
CC=arm-linux-gcc ./configure --prefix=$PREFIX --shared
make
make install

6) libpng
./configure --host=arm-linux --prefix=$PREFIX
make
make install

7) expat
./configure --host=arm-linux  --prefix=$PREFIX
make
make install
8) freetype
./configure --host=arm-linux  --prefix=$PREFIX
make
make install

9) libxml
./configure --host=arm-linux  --prefix=$PREFIX
make
make install

10) fontconfig
export LIBXML2_CFLAGS=-I$PREFIX/include/libxml2
export LIBXML2_LIBS="-L$PREFIX/lib -lxml2"
./configure --host=arm-linux --prefix=$PREFIX --with-freetype-config=$PREFIX/bin/freetype-config --with-arch=arm
make
make install

11) tiff
./configure --host=arm-linux --prefix=$PREFIX --enable-shared
make
make install

12) DirectFB
./configure --host=arm-linux --prefix=$PREFIX --with-gfxdrivers=none --with-inputdrivers=all --enable-png --enable-jpeg --disable-tiff --enable-zlib --enable-sdl=no --enable-gif=no --disable-x11
make
make install

13) cairo
./configure --host=arm-linux --prefix=$PREFIX --without-x --disable-xlib --disable-xlib-xrender --enable-directfb --enable-freetype --disable-win32 --enable-pdf --enable-ps --disable-svg --enable-png
make
make install

      不知道爲什麼,gtk非要有pdf和ps的支持,沒有就無法完成configure,沒辦法,我只好在這裏就打開,其實也不能真正支持,因爲pdf等東西根本沒有加進來。不知道後來的gtk版本有無改進。
14) Pango
     修改configure文件,將下面一些參數改成true
have_cairo=true
have_cairo_png=true         
have_cairo_ps=true
have_cairo_pdf=true
have_cairo_freetype=true
./configure --host=arm-linux --prefix=$PREFIX --enable-cairo --without-x
make
make install

15) gtk
export LDFLAGS="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib"
export CPPFLAGS="-I$PREFIX/include"
./configure --host=arm-linux --prefix=$PREFIX --with-gdktarget=directfb --without-x --without-libtiff
make
make install
5 開發板運行環境
    開發板的內核是2.6的,一切驅動都已完畢,文件系統採用nfs加載,在宿主系統上位於/arm/root/root_nfs上,我是編譯好後,才弄板子的,但最好,在編譯之前,最好先熟悉熟悉開發板,我弄好好幾天才使開發板運行起來,因爲2.6的kernel使用的uboot裏某些東西跟2.4 kernel使用的uboot不同。我以前根本沒有弄過,困擾了好幾天。
在宿主系統上,將/usr/gtkdfb目錄複製到/arm/root/root_nfs/usr目錄下,開發板運行起來後,編譯好的東西都會在/usr/gktdfb目錄下。
1) Pangorc
mkdir /arm/root/root_nfs/usr/gtkdfb/etc/pango
創建文件 /arm/root/root_nfs/usr/gtkdfb/etc/pango/pangorc文件內容如下
# pangorc file for uninstalled operation.
# We set the path as ../modules, such that it works from any of
# top level build subdirs.
#

[Pango]
ModuleFiles = /usr/gtkdfb/etc/pango/pango.modules
ModulesPath = /usr/gtkdfb/lib/pango/1.6.0/modules

上面在宿主系統上運行
下面的命令在開發板上運行
/usr/gtkdfb/bin/pango-querymodules > /usr/gtkdfb/etc/pango/pango.modules
2) gfxdrivers
     下面的命令本行在開發板上運行,只是消除一個警告
mkdir /usr/gtkdfb/lib/directfb-1.1-0/gfxdrivers
3) gdk-pixbuf.loaders
     下面的命令本行在開發板上運行
mkdir /usr/gtkdfb/etc/gtk-2.0
/usr/gtkdfb/bin/gdk-pixbuf-query-loaders > /usr/gtkdfb/etc/gtk-2.0/gdk-pixbuf.loaders

4) gtk.immodules
     下面的命令本行在開發板上運行
/usr/gtkdfb/bin/gtk-query-immodules-2.0 > /usr/gtkdfb/etc/gtk-2.0/gtk.immodules
5) fonts.conf
     在/usr/gtkdfb/etc/fonts目錄下有fonts.conf這麼個文件,在這個文件配置了一些字庫的信息,在宿主系統中打開文件/arm/root/root_nfs/usr/gtkdfb/etc/fonts/fonts.conf,修改<!-- Font directory list -->這行以下的東西,設置正確的字庫目錄。當然前提需要將字庫複製到/arm/root/root_nfs的合適目錄下。比如ubuntu的設置如下
<!-- Font directory list -->
        <dir>/usr/share/fonts</dir>
        <dir>/usr/X11R6/lib/X11/fonts</dir>
        <dir>~/.fonts</dir>

最簡單的方法就是將ubuntu的這些目錄裏的內容複製到/arm/root/root_nfs相對目錄下,這樣,這個文件都可以不修改。但最後你肯定不能這樣做,因爲嵌入式是不需要這麼多字庫的,我們只要需要的,不需要的統統砍掉,瞭解一下這個文件也應該是必須的。
6) directfbrc
      這個文件我還沒用過,我曾經相弄它,因爲當初碰到一個問題以爲是他的問題,但不是它的問題,所以到現在爲止,我還沒弄。論壇上VCVC0說,沒有這個文件,程序加載很慢,有了,就快很多,這裏給個鏈接,我就不詳述
http://www.directfb.com.cn/viewthread.php?tid=373
下面是帖子的內容。也現在也不臆想我的用法了
如何配置基於arm的directfbrc配置文件?
我在我的開發板裏跑了一下應用。如果/etc目錄下沒有directfbrc文件的話,程序需要很久才能顯示出來。
我簡單設置了一下directfbrc內容如下:
system=fbdev
fbdev=/dev/fb/0
wm=default
mode=640x480
depth=32
pixelformat=RGB32
程序的啓動速度就快了很多,不知道是什麼原因。

還有問題就是direct的wm能否管理gtk的窗口。或者有沒有基於嵌入式開發的窗口管理器可以使用的。
6 最後的祕笈
    現在你在板子上運行GTK源碼包裏的test,應該是沒有問題,如果有問題,就要回頭苦修了。最後的一個問題來了,usb鼠標可以控制屏幕上的鼠標指針,觸屏不反應,明明我的tslib測試程序運行一定問題也沒有,DFB編譯也正確失敗了tslib這個庫,怎麼回事呢? 這就是最後的祕笈,我只所以敢將本文檔稱爲至尊祕笈,也就因爲這個祕笈,我認爲,解決這個問題需要相當的技術水平。
     首先,要說明這個問題都是複雜的。先說DFB的初始化,DFB加載先讀directfbrc,讀取一些設置,然後加載輔助模塊,模塊的加載都是動態的,採用dlopen方式加載的。tslib加載一些模塊也是採用這種方式加載的。應用程序動態鏈接到DFB的庫,加載能加載的模塊,同時加載了libdirectfb_tslib.so,這個模塊動態鏈接到libts.so這個庫,動態加載libdirectfb_tslib.so同時做一些初始化tslib的工作,初始tslib又會動態加載tslib的一些模塊,這四個模塊pthres、variance、dejitter、linear會用到libts.so這個庫裏的一個函數tslib_parse_vars,由於libdirectfb_tslib.so是用dlopen加載的,加載tslib的上四個模塊時,根本就不知道到何處去找函數tslib_parse_vars,而tslib的測試程序已經動態鏈接了libts.so,加載tslib的上速模塊時能夠正確識別函數tslib_parse_vars。
      原因知道了,解決問題就簡單了。鏈接應用程序時動態鏈接到庫libts.so就可以了,我修改gtk源碼tests目錄下的Makefile
LDFLAGS = -L/usr/gtkdfb/lib -lts -Wl,-rpath,/usr/gtkdfb/lib
重新編譯了這些測試程序,複製到開發板上,運行,一切都OK了
7 結語
      回想起來,搭建一個嵌入式的DFB+GTK的GUI開發平臺真的很困難,且不說如此多不同組織和個人編寫的包,就是每個人的環境也是千差萬別的,能夠給你提供幫助的人幾乎沒有,碰到問題,你只能在浩瀚的網絡裏找尋解決的方法。解決任何一個問題也許都要耗費巨大的精力。如果你的項目資金允許,還是請支持一下國產的優秀GUI軟件――MiniGUI,你碰到的問題,應該都很得到迅速,圓滿的解決,無疑會加快你的項目開發進度。當然,DFB+GTK也是很好的選擇,在你自己解決問題的時候,你會學到很多的東西,還會帶給你帶來巨大的成就感。
    最後,要感謝這些開源軟件包的寫作者們,是他們無私的奉獻,才讓我們能夠有機會學習這些優秀的代碼。還要感謝哪些在網上共享了自己經驗的先驅們,是他們的點點星火,給了我靈感,爲我指引瞭解決問題的方向。謹以本文獻給他們,再次感謝他們。同時,將本文獻給www.directfb.com.cn及壇主echo先生以及論壇的每一個現在的和將來的會員。我只不過在論壇上發表了兩篇很短小的陋文,echo先生竟邀請我當版主,使我倍感榮幸。
    環境的搭建工作我基本完成了,項目的需要,我要做其他的事情了。如果你也在做類似的工作,碰到了一些問題,希望本文能給你幫助。如果你在其他地方看到本文(本人希望有網站轉載本文),請訪問www.direcfb.com.cn,也許你能的得到更多的信息。


免責聲明: 本人不保證本文檔完全正確,如果你看到有什麼不合適的地方,歡迎與本人交流。

 

 

 


對於整個環境的建立,建議還是看這篇文章http://www.directfb.com.cn/viewthread.php?tid=383&extra=page%3D4 《嵌入式linux GUI--DirectFB + GTK至尊祕笈》
正如所說,建議先搞定tslib,qq2440開發版環境與祕籍中的環境看來是又點區別,編譯tslib過程如下
export PREFIX=/usr/local/directfb
export LDFLAGS=-L$PREFIX/lib
export CFLAGS="-O2 -Wall -W -DUSE_INPUT_API -I$PREFIX/include"
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig

echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --prefix=$PREFIX --cache-file=arm-linux.cache --enable-debug
make
make install

注意-DUSE_INPUT_API這個宏,從源代碼可以看出它控制着是否使用/dev/input/event0

接下來按祕訣中所說應該不會有什麼問題了,不過一定要注意的意見事是關於PREFIX,可以看到我所用的是PREFIX=/usr/local/directfb,所以當編譯好之後應該將$PREFIX之下的所用文件再拷貝到開發板的/usr/local/directfb目錄下,尤其對於使用nfs系統的朋友,經常會造成主機路徑和開發板路徑不一樣的情況,這也是很多找不到system,找不到id,之類錯誤的根源
   因爲觸摸屏屬於鼠標類設備,所以請將gdk_display_open()中的DIDID_KEYBOARD改爲DIDID_MOUSE,注我用的是gtk+-2.12.12
剩下什麼問題就google吧!!
下面是我開發板上的一些配置,僅供參考:
系統環境dfbenv.rc
#!/bin/sh
export PATH=/usr/local/directfb/bin:$PATH
export LD_LIBRARY_PATH=/lib:/usr/local/directfb/lib:/usr/local/directfb/lib/directfb-1.3-0:/usr/local/directfb/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb/0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/usr/local/directfb/etc/pointercal
export TSLIB_CONFFILE=/usr/local/directfb/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/directfb/lib/ts

ts.conf
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear

directfbrc:
no-debug
system=fbdev
fbdev=/dev/fb/0
wm=default
mode=240x320
depth=16
pixelformat=RGB16

在開發板上運行gtk-demo測試結果,開始顯示灰色背景,上面就一個水滴狀的鼠標指針,點一下屏幕後過會就變成常見的那種鼠標圖樣了,呵呵
不過再過會就會死掉,顯示 Caught signal 4 (at 0x4096e890, illegal opcode) ,還得繼續查啊
屏幕上除了鼠標其他什麼都沒有,看樣子還有不知道什麼地方有問題呢,對gtk,和directfb都不瞭解,這看來不好解決啊!
發現:不設置directfbrc文件 就不會出現“過會就死機”現象
發佈了35 篇原創文章 · 獲贊 4 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章