嵌入式Linux系統(tǒng)中的GUI系統(tǒng)的研究與移植
關(guān)鍵詞:嵌入式Linux GUI 應(yīng)用與移植 中文化
引言
嵌入式GUI為嵌入式系統(tǒng)提供了一種應(yīng)用于特殊場(chǎng)合的人們交互接口。嵌入式GUI要求簡(jiǎn)單、直觀、可靠、占用資源小且反應(yīng)快速,以適應(yīng)系統(tǒng)硬件資源有限的條件。另外,由于嵌入式系統(tǒng)硬件本身的特殊性,嵌入式GUI應(yīng)具備高度可移植性與可裁減性,以適應(yīng)不同的硬件條件和使用需求。總體來(lái)講,嵌入式GUI具備以下特點(diǎn):
*體積??;
*運(yùn)行時(shí)耗用系統(tǒng)資源??;
*上層接口與硬件無(wú)關(guān),高度可移植;
*高可靠性;
*在某些應(yīng)用場(chǎng)合應(yīng)具備實(shí)時(shí)性。
1 基于嵌入式Linux的GUI系統(tǒng)底層實(shí)現(xiàn)基礎(chǔ)
一個(gè)能夠移植到多種硬件平臺(tái)上的嵌入式GUI系統(tǒng),應(yīng)用至少抽象出兩類設(shè)備:基于圖形顯示設(shè)備(如VGA卡)的圖形抽象層GAL(Graphic Abstract Layer),基于輸入設(shè)備(如鍵盤,觸摸層等)的輸入抽象層IAL(Input Abstract Layer)。GAL層完成系統(tǒng)對(duì)具體的顯示硬件設(shè)備的操作,極大程度上隱蔽各種不同硬件的技術(shù)實(shí)現(xiàn)細(xì)節(jié),為誚程序開發(fā)人員提供統(tǒng)一的圖形編程接口。IAL層則需要實(shí)現(xiàn)對(duì)于各類不同輸入設(shè)備的控制操作,提供統(tǒng)一的調(diào)用接口。GAL層與IAL層的設(shè)計(jì)概念,可以極大程序地提高嵌入式GUI的可移植性,如圖1所示。
目前應(yīng)用于嵌入式Linux系統(tǒng)中比較成熟,功能也比較強(qiáng)大的GUI系統(tǒng)底層支持庫(kù)有SVGA lib、LibGGI、Xwindow、framebuffer等。
2 三種嵌入式GUI系統(tǒng)的分析與比較
2.1 Microwindows
Microwindows是一個(gè)典型的基于Server/Clinent體系結(jié)構(gòu)的GUI系統(tǒng),基本分為三層,如圖2所示。
最底層是面向圖形顯示和鍵盤、鼠標(biāo)或觸摸屏的驅(qū)動(dòng)程序;中間層提供底層硬件的抽象接口,并進(jìn)行窗口管理;最高層分別提供兼容于X Window和ECMA APIW(Win32子集)的API。其中使用Nano-X接口的API與X接口兼容,但是該接口沒(méi)有提供窗口管理,如窗口移動(dòng)和窗口剪切等高級(jí)功能,系統(tǒng)中需要首先啟動(dòng)nano-X的Server程序nanoxserver和窗口管理程序nanowm。用戶程序連接nano-X的Server獲得自身的窗口繪制操作。使用ECMA APIW編寫的應(yīng)用程序無(wú)需nanox-server和nanowm,可直接運(yùn)行。
Microwindows提供了相對(duì)完善的圖形功能和一些高級(jí)的特性,如Alpha混合、三維支持和TrueType字體支持等。該系統(tǒng)為了提高運(yùn)行速度,也改進(jìn)了基于Socket套接字的X實(shí)現(xiàn)模式,采用了基于消息機(jī)制的Server/Client傳輸機(jī)制。Microwindows也有一些通用的窗口控件,但其圖形引擎存在許多問(wèn)題,可以歸納如下:
*無(wú)任何硬件加速能力;
*圖形引擎中存在許多低效算法,如在圓弧圖函數(shù)的逐點(diǎn)判斷剪切的問(wèn)題。
由于該項(xiàng)目缺乏一個(gè)強(qiáng)有力的核心代碼維護(hù)人員,2003年Microwindows推出版本0.90后,該項(xiàng)目的發(fā)展開始陷于停滯狀態(tài)。
2.2 MiniGUI
MiniGUI是由國(guó)內(nèi)自由軟件開發(fā)人員設(shè)計(jì)開發(fā)的,目標(biāo)是為基于Linux的實(shí)時(shí)嵌入式系統(tǒng)提供一個(gè)輕量級(jí)的圖形用戶界面支持系統(tǒng)。MiniGUI的體系架構(gòu)如圖3所示。
MiniGUI分為最底層的GAL層和IAL層,向上為基于標(biāo)準(zhǔn)POSIX接口中pthread庫(kù)的Mini-thread架構(gòu)和基于Server/Client的Mini-Lite架構(gòu)。其中前者受限于thread模式對(duì)于整個(gè)系統(tǒng)的可靠性影響――進(jìn)程中某個(gè)thread的意外錯(cuò)誤可能導(dǎo)致整個(gè)進(jìn)程的崩潰,該架構(gòu)應(yīng)用于系統(tǒng)功能較為單一的場(chǎng)合。Mini-Lite應(yīng)用于多進(jìn)程的應(yīng)用場(chǎng)合,采用多進(jìn)程運(yùn)行方式設(shè)計(jì)的Server/Client架構(gòu)能夠較好地解決各個(gè)進(jìn)程之間的窗口管理、Z序剪切等問(wèn)題。MiniGUI還有一種從Mini-Lite衍生出的standalone運(yùn)行模式。與Lite架構(gòu)不同的是,standalone模式一次只能以窗口最大化的方式顯示一個(gè)窗口。這在顯示屏尺寸較小的應(yīng)用場(chǎng)合具有一定的應(yīng)用意義。
MiniGUI的GAL層技術(shù)SVGA lib、LibGGI、基于framebuffer的native圖形引擎以及啞圖形引擎等,對(duì)于Trolltech公司的QVFB在X Window下也有較好的支持。IAL層則支持Linux標(biāo)準(zhǔn)控制臺(tái)下的GPM鼠標(biāo)服務(wù)、觸摸屏、標(biāo)準(zhǔn)鍵盤等。
MiniGUI下豐富的控件資源也是MiniGUI的特點(diǎn)之一。當(dāng)前MiniGUI的最新版本是1.3.3。該版本的控件中已經(jīng)添加了窗口皮膚、工具條等桌面GUI中的高級(jí)控件支持。
2.3 QT/Embedded
Qt/Embedded是著名的Qt庫(kù)開發(fā)商Trolltech公司開發(fā)的面向嵌入式系統(tǒng)的Qt版本。因?yàn)镼t是KDE等項(xiàng)目使用的GUI支持庫(kù),許多基于Qt的X Window程序因此可以非常方便地移植到Qt/Embedded上。Qt/Embedded同樣是Server/Client結(jié)構(gòu)。
Qt/Embedded延續(xù)了Qt在X上的強(qiáng)大功能,在底層摒棄了X lib,僅采用framebuffer作為底層圖形接口。同時(shí),將外部輸入設(shè)備抽象為keyboard和mouse輸入事件,底層接口支持鍵盤、GPM鼠標(biāo)、觸摸屏以及用戶自定義的設(shè)備等。
Qt/Embedded類庫(kù)完全采用C++封裝。豐富的控件資源和較好的可移植性是Qt/Embedded最為優(yōu)秀的一方面。它的類庫(kù)接口完全兼容于同版本的Qt-X11,使用X下的開發(fā)工具可以直接開發(fā)基于Qt/Embedded的應(yīng)用程序QUI界面。
與前兩種GUI系統(tǒng)不同的是,Qt/Embedded的底層圖形引擎只能采用framebuffer。這就注定了它是針對(duì)高端嵌入式圖形領(lǐng)域的應(yīng)用而設(shè)計(jì)的。由于該庫(kù)的代碼追求面面俱到,以增加它對(duì)多種硬件設(shè)備的支持,造成了其底層代碼比較凌亂,各種補(bǔ)丁較多的問(wèn)題。Qt/Embedded的結(jié)構(gòu)也過(guò)于復(fù)雜臃腫,很難進(jìn)行底層的擴(kuò)充、定制和移植,尤其是用來(lái)實(shí)現(xiàn)signal/slot機(jī)制的moc文件。
Qt/Embedded當(dāng)前的最新版本為3.3.2,能夠支持Trolltech的手持應(yīng)用套件Qtopia的Qt/Embedded最高版本為2.3.8。Trolltech公司將于2004年末推出的Qt/Embedded 3為基礎(chǔ)的Qtopia 2應(yīng)用套件。
3 三種嵌入式GUI的移植與中文化
在進(jìn)行以上三種嵌入式GUI的研究和移植過(guò)程中,硬件平臺(tái)采用自行設(shè)計(jì)的以Motorola MC9328 MX1為核心的開發(fā)系統(tǒng)。該系統(tǒng)采用CPU內(nèi)部LCD控制器和320240分辨率的16bpp TFT LCD作為顯示設(shè)備,使用I2C總線擴(kuò)展出16按鍵的鍵盤,同時(shí)配置了9位A/D量化精度的電阻觸摸屏作為鼠標(biāo)類輸入設(shè)備;同時(shí)移植了ARM Linux作為操作系統(tǒng)。以下分別討論這三種嵌入式GUI的底層移植和中文化技術(shù)。
移植以上三種嵌入式GUI系統(tǒng),需要首先實(shí)現(xiàn)Linux內(nèi)核中的framebuffer驅(qū)動(dòng)。對(duì)應(yīng)于開發(fā)系統(tǒng)為MC9328中的LCD控制器,該部分驅(qū)動(dòng)程序必須以靜態(tài)方式編譯進(jìn)內(nèi)核,在系統(tǒng)啟動(dòng)時(shí)由傳遞進(jìn)內(nèi)核的啟動(dòng)參數(shù)激活該設(shè)備。I2C鍵盤的驅(qū)動(dòng)程序和觸摸屏的驅(qū)動(dòng)程序?qū)崿F(xiàn)后,作為L(zhǎng)inux內(nèi)核模塊在使用時(shí)動(dòng)態(tài)加載。
3.1 Microwindows的移植
Microwindows驅(qū)動(dòng)層相應(yīng)的源碼目錄為src/drivers/。其中以scr*開頭的源碼是針對(duì)顯示設(shè)備的驅(qū)動(dòng)接口,以mou*開頭的源碼文件為鼠標(biāo)設(shè)備(包括觸摸屏)的驅(qū)動(dòng)接口,以kbd*開頭的源碼文件針對(duì)鍵盤設(shè)備的驅(qū)動(dòng)接口。移植過(guò)程中需要實(shí)現(xiàn)自己的設(shè)備驅(qū)動(dòng)接口提供給Microwindows使用,就必須按照指定的接口格式編寫相應(yīng)的scr、mou、kbd的底層支持。這種方式實(shí)現(xiàn)簡(jiǎn)單,條理也很清晰。
顯示設(shè)備驅(qū)動(dòng)接口:Microwindows的圖形發(fā)生引擎支持framebuffer,修改src/中的config文件指定使用framebuffer作為底層圖形支持引擎;但需要注意嵌入式Linux的framebuffer較少支持控制臺(tái)字符模式,需要修改Microwindows中對(duì)framebuffer的操作部分以關(guān)閉顯示模式的轉(zhuǎn)換。
在應(yīng)用程序開發(fā)移植中需要注意的是:使用ECMAAPIW接口設(shè)計(jì)的程序無(wú)需nano-X的Server程序和nanowm,如圖2所示。系統(tǒng)中可以直接啟動(dòng)使用該接口編寫的用戶程序;但需要注意的是,一個(gè)系統(tǒng)中如同時(shí)存在使用兩種不同的API接口編寫的進(jìn)程,會(huì)造成nano-X的Server與ECMA APIW的進(jìn)程對(duì)系統(tǒng)硬件資源的使用競(jìng)爭(zhēng),雙方的程序?qū)o(wú)法正常顯示或響應(yīng)應(yīng)用戶輸入。
在為Microwindows增加中文顯示的支持時(shí),主要工作包括兩個(gè)部分。一部分是系統(tǒng)字體的中文支持。此處使用等寬光柵字體,主要負(fù)責(zé)窗口標(biāo)題和內(nèi)置控件的中文繪制,將字體編譯進(jìn)Microwindows內(nèi)核中,光柵信息作為一維數(shù)組,顯示時(shí)按照字符偏移量從該數(shù)組中調(diào)出相應(yīng)的光柵信息顯示即可。除此之外,當(dāng)程序調(diào)用CreateFont時(shí),需要在內(nèi)部實(shí)現(xiàn)為打開文件系統(tǒng)中的字體文件。通過(guò)修改src/engine/devfont.c中的GdCreateFont部分,添加相應(yīng)的hzk(漢字庫(kù))支持,便可以實(shí)現(xiàn)在CreateFont時(shí)創(chuàng)建出一個(gè)支持GB2312字符集的邏輯字體,并使用外部字體進(jìn)行顯示。在應(yīng)用程序設(shè)計(jì)時(shí),如果沒(méi)有調(diào)用SelectObjectu將外部字體選入,中文顯示時(shí)將默認(rèn)使用系統(tǒng)字體。
3.2 MiniGUI
由于MiniGUI較好地將硬件設(shè)備抽象為GAL層和IAL層,移植時(shí)只需要針對(duì)自身的硬件特點(diǎn)按照GAL層調(diào)用接口和IAL層調(diào)用接口來(lái)做內(nèi)部實(shí)現(xiàn)即可。圖4為MiniGUI的GAL層結(jié)構(gòu)示意,IAL層結(jié)構(gòu)類似。
實(shí)現(xiàn)了framebuffer的Linux驅(qū)動(dòng)后,配置MiniGUI選擇Native的GAL引擎,便可以使用framebuffer作為MiniGUI的圖形發(fā)生引擎。
MiniGUI的IAL層將輸入設(shè)備的輸入事件最終映射為GUI系統(tǒng)API層的消息事件。IAL層默認(rèn)處理兩種設(shè)備的輸入操作:鍵盤設(shè)備和鼠標(biāo)設(shè)備。鍵盤設(shè)備向上層提供不同的按鍵輸入信息,鼠標(biāo)設(shè)備提供點(diǎn)擊、抬起和落筆坐標(biāo)等的信息。在實(shí)現(xiàn)MiniGUI與輸入設(shè)備驅(qū)動(dòng)的接口時(shí),采用Select的方式獲得輸入設(shè)備的動(dòng)作,并轉(zhuǎn)換為消息隊(duì)列中的消息。消息參數(shù)按照Win32接口定義為點(diǎn)擊鍵編號(hào)或鼠標(biāo)當(dāng)前的坐標(biāo)(其中觸摸屏事件與鼠標(biāo)事件類似)。通過(guò)編寫針對(duì)硬件開發(fā)系統(tǒng)的IAL支持代碼,實(shí)現(xiàn)了IAL層的移植。
MiniGUI中多字體和字符集支持是通過(guò)設(shè)備上下文(DC)的邏輯字體(LOGFONT)實(shí)現(xiàn)的,創(chuàng)建邏輯字體時(shí)指定相應(yīng)的字符集,其內(nèi)部實(shí)現(xiàn)為對(duì)于所需顯示字符的所屬字符集的識(shí)別處理,最終調(diào)用相應(yīng)字符集的處理函數(shù)族。應(yīng)用程序在啟動(dòng)時(shí),可切換系統(tǒng)字符集,如GB2312、BIG5、EUCKR、UJIS。MiniGUI的這種字符集支持方式不同于采用UNICODE的解決方案。在節(jié)省系統(tǒng)資源的意義上講,這種實(shí)現(xiàn)更加適合于嵌入式系統(tǒng)應(yīng)用,是MiniGUI的一大創(chuàng)新點(diǎn)。MiniGUI同時(shí)支持包括ttf、bdf、type 1、vbf等多種字體格式,可以根據(jù)需要配置MiniGUI來(lái)支持相應(yīng)字體的顯示。
3.3 Qt/Embedded的移植
Qt/Embedded的底層圖形引擎完全依賴于framebuffer,因此在移植時(shí)需考慮目標(biāo)平臺(tái)的Linux內(nèi)核版本和framebuffer驅(qū)動(dòng)程序的實(shí)現(xiàn)情況,包括分辨率和顏色深度等在內(nèi)的信息。當(dāng)前嵌入式CPU大多內(nèi)部集成LCD控制器,并支持多種配置方式。除少數(shù)CPU低色彩配置時(shí)的endian問(wèn)題外,Qt/Embedded能夠較好地根據(jù)系統(tǒng)已有的framebuffer驅(qū)動(dòng)接口構(gòu)建上層的圖形引擎。
Qt/Embedded圖形發(fā)生引擎中的圖形繪制操作函數(shù)都是由源泉碼目錄src/kernel/中的src/kernel/qgfxreaster_qws.cpp中所定義的QgfxRasterBase類發(fā)起聲明的。對(duì)于設(shè)備更加底層的抽象描述,則在src/kernel目錄中的qgfx_qws.cpp中的Qscreen類中給予相應(yīng)定義。這些是對(duì)framebuffer設(shè)備直接操作的基礎(chǔ),包括點(diǎn)、線、區(qū)域填充、alpha混合、屏幕繪制等函數(shù)均在其中定義實(shí)現(xiàn)。在framebuffer驅(qū)動(dòng)程序調(diào)試通過(guò)后,配置Qt/Embedded的編譯選項(xiàng),可以保證Qt/Embedded的圖形引擎正常工作。
Qt/Embedded中的輸入設(shè)備,同樣分為鼠標(biāo)類與鍵盤類。其中鼠標(biāo)設(shè)備在源泉碼目錄中的src/kernel/qwsmouse_qws.cpp中實(shí)現(xiàn),從該類又重新派生出一些特殊鼠標(biāo)類設(shè)備的實(shí)現(xiàn)類,其派生結(jié)構(gòu)如圖5所示。
根據(jù)具體的硬件驅(qū)動(dòng)程序?qū)崿F(xiàn)的接口,可以實(shí)現(xiàn)類似的接口函數(shù)。
Qt/Embedded中對(duì)于鍵盤響應(yīng)的實(shí)際函數(shù)位于src/kernel/qkeyboard_qws.cpp中,在qkeyboard_qws.h中,定義了鍵盤類設(shè)備接口的基類QWSKeyboardHandler。具體的鍵盤硬件接口依然要建立在鍵盤驅(qū)動(dòng)程序基礎(chǔ)上,移植時(shí)需要根據(jù)鍵盤驅(qū)動(dòng)程序從該類派生出實(shí)現(xiàn)類,實(shí)現(xiàn)鍵盤事件處理函數(shù)processKeyEvent()即可。
Qt/Embedded內(nèi)部對(duì)于字符集的處理采用了UNICODE編碼標(biāo)準(zhǔn)。Qt/Embedded內(nèi)部對(duì)于字符集的處理采用了UNICODE編碼標(biāo)準(zhǔn)。Qt/Embedded同時(shí)支持兩種對(duì)于其它編碼標(biāo)準(zhǔn)(如GB2312和GBK)的支持方式:靜態(tài)編譯和動(dòng)態(tài)插件裝載。通過(guò)配置config.h文件添加相應(yīng)的編碼支持宏定義,可以獲得其它編碼標(biāo)準(zhǔn)向UNICODE的轉(zhuǎn)換支持,從而在Qfont類中得以轉(zhuǎn)換與顯示。由于UNICODE涵蓋了中文部分,Qt/Embedded對(duì)中文支持也非常好。
Qt/Embedded能夠支持TTF、PFA/PFB、BDF 和QPF字體格式。由于自身采用UNICODE編碼方式對(duì)字符進(jìn)行處理,在一定程序上導(dǎo)致了能夠使用的字體文件體積的增大。為了解決這一問(wèn)題,Qt/Embedded采用了QPF格式,使用makeqpf等工具可以將TTF等格式的字體轉(zhuǎn)換至QPF格式。圖6為筆者在自行設(shè)計(jì)的MC9328系統(tǒng)上移植Qt/Embedded和Qtopia套件后,增加中文支持后的顯示截圖。Qt/Embedded版本為2.3.7,Qtopia版本為1.7.0。
4 結(jié)論
綜上所述,一個(gè)具備良好移植性的嵌入式GUI系統(tǒng),其底層接口應(yīng)該在很大程度上隱藏具體硬件的實(shí)現(xiàn)細(xì)節(jié),抽象出GAL與IAL層。對(duì)于字符集的支持,也可以從MiniGUI的字符集支持方式和Qt/Embedded的UNICODE支持方式上獲得啟發(fā)。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論