<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Qt/Embedded在嵌入式Linux系統中的應用

Qt/Embedded在嵌入式Linux系統中的應用

作者: 時(shí)間:2005-04-12 來(lái)源:網(wǎng)絡(luò ) 收藏

摘要:分析和討論的主流版本3.x系列的底層實(shí)現技術(shù);結合2.x版本系列和3.x版本系列,在兩種不同的硬件平臺(Intel PXA255開(kāi)發(fā)與筆者自行設計的Motorola MC9328 MX1開(kāi)發(fā))上的移植過(guò)程,討論的底層設備接口與移植技術(shù)。

關(guān)鍵詞: framebuffer 驅動(dòng)接口

引言

隨著(zhù)的不斷發(fā)展,處理器運算能力的不斷增強,越來(lái)越多的嵌入式設備開(kāi)始采用較為復雜的GUI,手持設備中的GUI系統發(fā)展得非常迅速。傳統的GUI系統,如Microwindows等,由于項目規模較小、功能較為薄弱,缺乏等三方軟件開(kāi)發(fā)的支持等諸多原因,在比較高級的手持或移動(dòng)終端設備(如PDA、Smart-Phone、車(chē)載導航系統)中較少。

Qt/Embedded是著(zhù)名的Qt庫開(kāi)發(fā)商Trolltech公司開(kāi)發(fā)的面向嵌入式系統的Qt版本,開(kāi)發(fā)人員多為KDE項目的核心開(kāi)發(fā)人員。許多基于Qt的X Window程序可以非常方便地移植到Qt/Embedded上,與X11版本的Qt在最大程度上接口兼容,延續了在X上的強大功能,在底層徹底摒棄了X lib,僅采用framebuffer作為底層圖形接口。Qt/Embedded類(lèi)庫完全采用C++封裝。豐富的控件資源和較好的可移植性是Qt/Embedded最為優(yōu)秀的一方面,使用X下的開(kāi)發(fā)工具Qt Designer可以直接開(kāi)發(fā)基于Qt/Embedded的UI(用戶(hù)操作接口)界面。越來(lái)越多的第三方軟件公司也開(kāi)始采用Qt/Embedded開(kāi)發(fā)嵌入式下的應用軟件。其中非常著(zhù)名的Qt Palmtop Environment(Qtopia)早期是一個(gè)第三方的開(kāi)源項目,并已經(jīng)成功應用于多款高檔PDA。Trolltech公司針對Smart-Phone中的應用需求,于2004年5月底發(fā)布了Qtopia的Phone版本。

1 Qt/Embedded的實(shí)現技術(shù)基礎分析

橫向來(lái)看,由于發(fā)布的版權問(wèn)題,Qt/Embedded采用兩種方式進(jìn)行發(fā)布:在GPL協(xié)議下發(fā)布的free版與專(zhuān)門(mén)針對商業(yè)應用的commercial版本。二者除了發(fā)布方式外,在源碼上沒(méi)有任何區別??v向看來(lái),當前主流的版本為Qtopia的2.x系列與最新的3.0x系列。其中2.0版本系統較多地應用于采用Qtopia作為高檔PDA主界面的應用中;3.x版本系列則應用于功能相對單一,但需要高級GUI圖形支持的場(chǎng)合,如Volvo公司的遠程公交信息系統。圖1為Qt/Embedded的實(shí)現結構。

3.x版本系列的Qt/Embedded相對于2.x版本系統增加了許多新的模塊,如SQL數據庫查詢(xún)模塊等。幾乎所有2.x版本中原有的類(lèi)庫,在3.x版本中都得到極大程度的增強。這就極大地縮短了應用軟件的開(kāi)發(fā)時(shí)間,擴大了Qt/Embedded的應用范圍。

在代碼設計上,Qt/Embedded巧妙地利用了C++獨有的機制,如繼承、多態(tài)、模板等,具體實(shí)現非常靈活。但其底層代碼由于追求與多種系統、多種硬件的兼容,代碼補丁較多,風(fēng)格稍顯混亂。

1.1 Qt/Embedded的圖形引擎實(shí)現基礎

Qt/Embedded的底層圖形引擎基于framebuffer。Framebuffer是在Linux內核架構版本2.2以后推出的標準顯示設備驅動(dòng)接口。采用mmap系統調用,可以將framebuffer的顯示緩存映射為可連續訪(fǎng)問(wèn)的一段內存儲針。由于目前比較高級的ARM體系的嵌入式CPU中大多集成了LCD控制模塊,LCD控制模塊一般采用雙DMA控制器組成的專(zhuān)用DMA通道。其中一個(gè)DMA可以自動(dòng)從一個(gè)數據結構隊列中取出并裝入新的參數,直到整個(gè)隊列中的DMA操作都已完成為止。另外一個(gè)DMA與畫(huà)面緩沖區相關(guān),這部分由兩個(gè)DMA控制器交替執行,并每次都自動(dòng)按照預定的規則改變參數。雖然使用了雙DMA,但這兩個(gè)DMA控制器的交替使用對于CPU來(lái)說(shuō)是不可見(jiàn)的。CPU所獲得的只是由兩個(gè)DMA組成的一個(gè)“通道”而已。

Framebuffer驅動(dòng)程序的實(shí)現分為兩個(gè)方面:一方面是對LCD及其相關(guān)部分的初始化,包括畫(huà)在緩沖區的創(chuàng )建和對DMA通道的設置;另外一方面是對畫(huà)面緩沖區的讀寫(xiě),具體到代碼為read、write、lseek等系統調用接口。至于將畫(huà)面緩沖區的內容輸出到LCD顯示屏上,則由硬件自動(dòng)完成。對于軟件來(lái)說(shuō)是透明的。當對于DMA通道和畫(huà)面緩沖區設置完成后,DMA開(kāi)始正常工作,并將緩沖區中的內容不斷發(fā)送到LCD上。這個(gè)過(guò)程是基于DMA對于LCD的不斷刷新的?;谠撎匦?,framebuffer驅動(dòng)程序必須將畫(huà)面緩沖區的存儲空間(物理空間)重新映射到一個(gè)不加高緩存和寫(xiě)緩存的虛擬地址區間中,這樣能才保證應用程序通過(guò)mmap將該緩存映射到用戶(hù)空間后,對于該畫(huà)面緩存的寫(xiě)操作能夠實(shí)時(shí)的體現在LCD上。

在Qt/Embedded中,Qscreen類(lèi)為抽象出的底層顯示設備基類(lèi),其中聲明了對于顯示設備的基本描述和操作方式,如打開(kāi)、關(guān)閉、獲得顯示能力、創(chuàng )建GFX操作對象等。另外一個(gè)重要的基類(lèi)是QGfx類(lèi)。該類(lèi)抽象出對于顯示設備的具體操作接口(圖形設備環(huán)境),如選擇畫(huà)刷、畫(huà)線(xiàn)、畫(huà)矩形、alpha操作等。以上兩個(gè)基類(lèi)是Qt/Embedded圖形引擎的底層抽象。其中所有具體函數基本都是虛函數,Qt/Embedded對于具體的顯示設備,如Linux的framebuffer、Qt Virtual Framebuffer做的抽象接口類(lèi)全都由此繼承并重載基類(lèi)中的虛函數實(shí)現。圖2為Qt/Embedded中底層圖形引擎實(shí)現結構。

圖2

在圖2中,對于基本的framebuffer設備,Qt/Embedded用QlinuxFbScreen來(lái)處理。針對具體顯示硬件(如Mach卡、Voodoo卡)的加速特性,Qt/Embedded從QlinuxFbScreen和圖形設備環(huán)境模板類(lèi)QgfxRasterdepth,type>繼承出相應子類(lèi),并針對相應硬件重載相關(guān)虛函數。

Qt/Embedded在體系上為C/S結構,任何一個(gè)Qt/Embedded程序都可以作為系統中唯一的一個(gè)GUI Server存在。當應用程序首次以系統GUI Server的方式加載時(shí),將建立QWSServer實(shí)體。此時(shí)調用QWSServer::openDisplay()函數創(chuàng )建窗體,在QWSServer::openDisplay()中對QWSDisplay::Data中的init()加以調用;根據QgfxDriverFactory實(shí)體中的定義(QLinuxFbScreen)設置關(guān)鍵的Qscreen指針qt_screen并調用connect()打開(kāi)顯示設備(dev/fb0)。在QWSServer中所有對于顯示設備的調用都由qt_screen發(fā)起。至此完成了Qt/Embedded中QWSServer的圖形發(fā)生引擎的創(chuàng )建。當系統中建立好GUI Server后,其它需要運行的Qt/Embedded程序在加載后采用共享內存及有名管道的進(jìn)程通信方式,以同步訪(fǎng)問(wèn)模式獲得對共享資源framebuffer設備的訪(fǎng)問(wèn)權。

1.2 Qt/Embedded的事件驅動(dòng)基礎

Qt/Embedded中與用戶(hù)輸入事件相關(guān)的信號,是建立在對底層輸入設備的接口調用之上的。Qt/Embedded中的輸入設備,分為鼠標類(lèi)與鍵盤(pán)類(lèi)。以3.x版本系列為例,其中鼠標設備的抽象基類(lèi)為QWSMouse Handler,從該類(lèi)又重新派生出一些具體的鼠標類(lèi)設備的實(shí)現類(lèi)。該版本系列的Qt/Embedded中,鼠標類(lèi)設備的派生結構如圖3所示。

與圖形發(fā)生引擎加載方式類(lèi)似的,在系統加載構造QWSServer時(shí),調用QWSServer::openMouse與QWSServer::openKeyboard函數。這兩個(gè)函數分別調用QmouseDriverFactory::create()與QkbdDriverFactory::create()函數。這時(shí)會(huì )根據Linux系統的環(huán)境變量QWS_MOUSE_PROTO與QWS_KEYBOARD獲得鼠標類(lèi)設備和鍵盤(pán)類(lèi)設備的設備類(lèi)型和設備節點(diǎn)。打開(kāi)相應設備并返回相應設備的基類(lèi)句柄指針給系統,系統通過(guò)將該基類(lèi)指令強制轉換為對應的具體子類(lèi)設備指針,獲得對具體鼠標類(lèi)設備和鍵盤(pán)類(lèi)設備的調用操作。

值得注意的是,雖然幾乎鼠標類(lèi)設備的功能上基本一致,但由于觸摸屏和鼠標底層接口并不一樣,會(huì )造成對上層接口的不一致。舉例來(lái)講,從鼠標驅動(dòng)接口中幾乎不會(huì )得到絕對位置信息,一般只會(huì )讀到相對移動(dòng)量。另外,鼠標的移動(dòng)速度也需要考慮在內,而觸摸屏接口則幾乎是清一色的絕對位置信息和壓力信息。針對此類(lèi)差別,Qt/Embedded將同一類(lèi)設備的接口部分也給予區別和抽象,具體實(shí)現在QmouseDriverInterface類(lèi)中。鍵盤(pán)類(lèi)設備也存在類(lèi)似問(wèn)題,同樣引入了QkbdDriver Inteface來(lái)解決。具體實(shí)現此處暫不多述。

2 Qt/Embedded的移植與應用

針對Qt/Embedded的實(shí)現特點(diǎn),移植該嵌入式GUI系統一般分為以下幾個(gè)步驟:

①設計硬件開(kāi)發(fā)平臺,并移植Linux操作系統;

②采用靜態(tài)鏈接進(jìn)Linux內核的方式,根據該平臺顯示設備的顯示能力,開(kāi)發(fā)framebuffer驅動(dòng)程序;

③開(kāi)發(fā)針對該平臺的鼠標類(lèi)設備驅動(dòng)程序,一般為觸摸屏或USB鼠標;

④開(kāi)發(fā)針對該平臺的鍵盤(pán)類(lèi)設備驅動(dòng)程序,一般為板載按鈕或USB鍵盤(pán)(該部分可選);

⑤根據framebuffer驅動(dòng)程序接口,選擇并修改Qt/Embedded中的QlinuxFbScreen和QgfxRaster類(lèi);

⑥根據鼠標類(lèi)設備驅動(dòng)程序,實(shí)現該類(lèi)設備在Qt/Embedded中的操作接口;

⑦根據鍵盤(pán)類(lèi)設備驅動(dòng)程序,實(shí)現該類(lèi)設備在Qt/Embedded中的操作接口(該部分可選);

⑧根據需要選擇Qt/Embedded的配置選項,交叉編譯Qt/Embedded的動(dòng)態(tài)庫;

⑨交叉編譯Qt/Embedded中的Example測試程序,在目標平臺上運行測試。

Framebuffer設備驅動(dòng)程序提供出的接口是標準的,除了注意endian問(wèn)題外,配置Qt/Embedded時(shí)選擇相應的色彩深度支持即可,因此該部分的移植難點(diǎn)就在于framebuffer驅動(dòng)程序的實(shí)現。Qt/Embedded部分的QWSServer打開(kāi)/dev/中的framebuffer設備后讀出相應的顯示能力(屏幕尺寸、顯示色彩深度),模板QgfxRasterdepth.type>將根據色彩深度在用戶(hù)空間設備創(chuàng )建出與顯示緩存同樣大小的緩沖作為雙緩沖,并采用正確方式進(jìn)行顯示。

2.1 在PXA255平臺上移植和應用

在筆者參與設計的某Smart-Phone開(kāi)發(fā)平臺中,GUI系統實(shí)現方案采用了Qt/Embedded 2.3.7和Qtopia 1.7.0(基于Qt/Embedded 2.x系列的手持套件),硬件平臺采用了基于Intel XScale PXA255處理器的嵌入式開(kāi)發(fā)系統。該開(kāi)發(fā)系統采用640480分辨率的TFT LCD和PXA255內部LCD控制模塊作為顯示設備,ADS7846N作為外部電阻式觸摸屏控制器;另外,采用了五方向按鍵作為板載鍵盤(pán)。由于該系統采用了ISP1161作為USB Host控制器,較好地支持了USB接口的鍵盤(pán)和鼠標,操作系統為ARM Linux 2.4.19。參考Linux 2.4.19內核目錄drivers/input部分,可以按照標準內核中input device接口設計實(shí)現觸摸屏和鍵盤(pán),在實(shí)現了基于ISP1161的EHCI驅動(dòng)程序后,移植標準的USB接口的人機界面設備驅動(dòng)HID和USB鍵盤(pán)、鼠標的驅動(dòng)程序后,可以獲得對于該類(lèi)設備的調用接口。此過(guò)程不屬本文討論范疇,此處暫不多述。

Qt/Embedded 2.x系列對于輸入設備的底層接口與3.x系列不同,觸摸屏設備和鍵盤(pán)設備需要根據具體的驅動(dòng)程序接口在Qt/Embedded中設備實(shí)現對應的設備操作類(lèi)。其中對應于鼠標類(lèi)設備的實(shí)現位于src/kernel/qmouse_qws.cpp中。由于觸摸屏在實(shí)現原理上存在著(zhù)A/D量化誤差的問(wèn)題,因此所有的觸摸屏接口實(shí)現類(lèi)需要從特殊的QcalibratedMouseHandler繼承,并獲得校正功能。

Qt/Embedded 2.x中對于鍵盤(pán)響應的實(shí)現函數位于src/kernel/qkeyboard_qws.cpp中。在qkeyboard_qws.h中,定義了鍵盤(pán)類(lèi)設備接口的基類(lèi)QWSKeyboardHandler,移植時(shí)需要根據鍵盤(pán)驅動(dòng)程序從該類(lèi)派生出實(shí)現類(lèi),實(shí)現鍵盤(pán)事件處理函數processKeyEvent(),并在QWSServer::newKeyboardHandler函數中注冊自己的鍵盤(pán)類(lèi)設備即可。其中對于點(diǎn)擊鍵的鍵碼定義在Qt/Embedded的命名空間――src/kernel/qnamespace.h中。

圖4為筆者在該Smart-Phone開(kāi)發(fā)平臺上移植Qt/Embedded 2.3.7和Qtopia 1.7.0后顯示的截圖。

2.2 在MC9328平臺上移植和應用

在某車(chē)載導航輔助系統的開(kāi)發(fā)平臺設計中,采用了Qt/Embedded 3.3.2版本作為其GUI系統的實(shí)現方案。硬件平臺采用自行設計的以Motorola MC9328 MX1為核心的開(kāi)發(fā)系統。該系統采用CPU內部LCD控制器和240320分辨率的16 bpp TFT LCD作為顯示設備,采用I2C總線(xiàn)擴展出16按鍵以及MX1集成的ASP模塊和電阻觸摸屏。操作系統為ARM Linux 2.4.18。

Qt/Embedded 3.x版本系統中與底層硬件接口相關(guān)部分的源碼位于src/embedded/目標中。該部分包含三類(lèi)設備的接口:framebufer、鼠標與鍵盤(pán)。參照該目標中相關(guān)設備的具體接口代碼,根據自身硬件臺增添接口即可。

由于系統LCD的岔道率為240320,物理尺寸較小,在實(shí)現其于該系統的framebuffer驅動(dòng)程序時(shí)并沒(méi)有將其本身與Linux字符控制臺設備掛靠,因此framebuffer并不具備TEXT模式的工作方式。在移植Qt/Embedded時(shí),無(wú)需作framebuffer設備的工作方式轉換。正確配置色彩顯示支持后,Qt/Embedded能夠在LCD顯示出正確的圖形。由于該平臺的顯示系統為縱向320行,在設計時(shí)考慮到人對于非手持設備的視覺(jué)習慣為寬度大于高度的觀(guān)察方式,為了符合這種習慣性的觀(guān)察方式,在移植Qt/Embedded時(shí)采用了Transformed的旋轉圖形顯示方式在軟件上實(shí)現了顯示方向的轉換變化。

鼠標設備接口這一基類(lèi)QWSMouseHandler的實(shí)現位于src/embedded/qmouse_qws.cpp中。與2.x版本系列不同的是,3.x中所有的Linux觸摸屏示例接口代碼均實(shí)現在src/embedded/qmouselinuxtp_qws.cpp中的QWSLinuxTPMouseHandler類(lèi)中。其中對于不同型號的觸摸屏的接口實(shí)現代碼,采用不同的宏定義和預編譯的方式將它們分隔開(kāi)。筆者還通過(guò)從QWSLinuxTPMouseHandler中繼承自身觸摸屏接口類(lèi),替代原有的QWSLinuxTPMouseHandlerPrivate類(lèi),而在QWSLinuxTPMouseHandler生成自身觸摸屏接口對象的方式,較好地將移植部分的代碼與原有比較混亂的代碼分隔開(kāi)來(lái)。

圖4

3.x中鍵盤(pán)接口基類(lèi)們于src/embedded/qkbd_qws.cpp中,為QWSKeyboardHandler。實(shí)現I2C總線(xiàn)擴展出的16鍵鍵盤(pán)接口類(lèi)方式與觸摸屏類(lèi)似,此處不多述。需要注意的是,Qt/Embedded提供了事件過(guò)濾器(key event filter)的接口,在鍵盤(pán)點(diǎn)擊事件從QWSServer截獲并發(fā)送到相應的client之前會(huì )經(jīng)過(guò)函數QWSServer::KeyboardFilter。在此函數中可以按照自身需求生成新的鍵盤(pán)點(diǎn)擊事件,而后利用QWSServer::sendKeyEvent()發(fā)送新的點(diǎn)擊事件到client中。利用該方式可以將各種鍵盤(pán)點(diǎn)擊無(wú)法輸入的unicode字符轉換出來(lái),從而可以在較少的按鍵鍵盤(pán)上實(shí)現多unicode字符輸入法。Qt/Embedded 3.x鍵盤(pán)接口的移植與鼠標設備接口類(lèi)似,此處不多述。

3 總結

隨著(zhù)嵌入式處理器運算能力的不斷提高,對外設支持的不斷豐富,嵌入式Linux系統的應用也逐漸增多。Qt/Embedded延續了Qt在桌面系統的所有功能,豐富的API接口和基于組件的編程模型使得嵌入式Linux系統中的應用程序開(kāi)發(fā)更加便捷。由于Qt/Embedded本身面向高端的手持設備和移動(dòng)設備,將成為未來(lái)嵌入式系統的主要GUI。

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


關(guān)鍵詞: 應用 系統 Linux 嵌入式 Qt/Embedded

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>