況 昊
(西華大學(xué),四川 成都610039)
編寫基于imx6開發(fā)的移動(dòng)終端上VGA的功能添加和優(yōu)化的詳細(xì)說明書是為了方便更多的人了解飛思卡爾imx6這個(gè)ARM CortexTM-A9架構(gòu)處理器性能和架構(gòu),同時(shí)能夠深入了解VGA的具體工作流程和結(jié)構(gòu),在了解VGA在內(nèi)核如何工作的過程當(dāng)中也會(huì)跟大家講解一下Linux內(nèi)核的基本屬性和結(jié)構(gòu)以及內(nèi)部驅(qū)動(dòng)管理和調(diào)用。
i.MX6是基于ARM CortexTM-A9架構(gòu)的高擴(kuò)展性多核系列嵌入式多媒體應(yīng)用處理器,普遍使用于工業(yè)控制、車載電腦控制、智能移動(dòng)終端、監(jiān)控設(shè)備、機(jī)頂盒、KTV點(diǎn)歌設(shè)備等方面。它的強(qiáng)力的3D圖像處理引擎、支持多種格式的視頻壓縮解壓功能和內(nèi)部集成的電源管理等優(yōu)點(diǎn)使得它成為優(yōu)秀的智能設(shè)備開發(fā)平臺(tái),同時(shí)由于他支持高規(guī)格的LCD顯示2×4XGA(2048×1536)或2×[1080p+WXGA(1280×720)],因此以前的一些能適用于Linux內(nèi)核的VGA驅(qū)動(dòng)需要我們嵌入式軟件開發(fā)人員進(jìn)行調(diào)整。
VGA也就是Video Graphic Array,即顯示繪圖陣列。它的接口是一個(gè)模擬信號(hào)接口,在顯示領(lǐng)域成為了一種成熟通用的顯示器標(biāo)準(zhǔn)接口,由于它的通用性和高性能適應(yīng)性被各種規(guī)格的顯示器在硬件上使用和支持。在當(dāng)今PC機(jī)以及各種顯示和控制設(shè)備中VGA得到大眾的歡迎,因此在進(jìn)行嵌入式軟件開發(fā)中VGA驅(qū)動(dòng)成為我們調(diào)試和開發(fā)的重中之重。本文以Linux2.6內(nèi)核和飛思卡爾IMX6處理器為系統(tǒng)的軟、硬件平臺(tái),詳細(xì)論述了基于framebuffer技術(shù)開發(fā)VGA顯示驅(qū)動(dòng)程序的方法。
VGA驅(qū)動(dòng)模塊結(jié)構(gòu)包含:平臺(tái)驅(qū)動(dòng)、LCD控制器驅(qū)動(dòng)、外設(shè)驅(qū)動(dòng)。進(jìn)行VGA的嵌入式開發(fā)主要是為Android系統(tǒng)嵌入VGA功能模塊讓我們的移動(dòng)終端可以通過VGA接口外接顯示器滿足客戶的要求,同時(shí)對(duì)VGA驅(qū)動(dòng)進(jìn)行的優(yōu)化能讓我們的系統(tǒng)可以充分發(fā)揮出飛思卡爾imx6處理器強(qiáng)勁的圖像處理和顯示功能提高用戶體驗(yàn)。
在實(shí)現(xiàn)一個(gè)功能或者解決某一個(gè)問題的時(shí)候,我們要經(jīng)過理論分析,推導(dǎo),簡化,逐步達(dá)到目的,因此我們首先應(yīng)該分析VGA驅(qū)動(dòng)結(jié)構(gòu)和工作流程,抓住關(guān)鍵點(diǎn)預(yù)計(jì)如何優(yōu)化顯示效果,其次分析如何添加驅(qū)動(dòng)到Linux內(nèi)核使LCD能夠正常顯示智能移動(dòng)終端通過VGA傳輸?shù)男盘?hào),最后結(jié)合VGA驅(qū)動(dòng)和LCD優(yōu)化顯示畫面,讓imx6處理器的優(yōu)秀性能能夠發(fā)揮出來。
圖1 總體結(jié)構(gòu)
(1)設(shè)備定義模塊描述。通過設(shè)置platform_device結(jié)構(gòu)變量mxc_fb_device定義設(shè)備。
(2)輸入、輸出。
表1 平臺(tái)驅(qū)動(dòng)模塊輸入、輸出
(3)模塊接口關(guān)系。定義相關(guān)平臺(tái)設(shè)備。
(4)函數(shù)。
表2 平臺(tái)驅(qū)動(dòng)模塊函數(shù)
(1)模塊描述。向系統(tǒng)注冊(cè)已經(jīng)被定義的設(shè)備,注冊(cè)狀態(tài)可被其他模塊檢測(cè)。
(2)模塊接口關(guān)系。注冊(cè):注冊(cè)平臺(tái)設(shè)備。查詢調(diào)用:被相關(guān)函數(shù)查詢?cè)O(shè)備注冊(cè)狀態(tài),并自動(dòng)調(diào)用probe函數(shù)。
(3)輸入輸出。無。
(4)函數(shù)。
表3 平臺(tái)驅(qū)動(dòng)模塊函數(shù)
(1)模塊描述。注冊(cè)和定義LCD控制器的設(shè)備驅(qū)動(dòng)。
(2)模塊接口關(guān)系。已經(jīng)被定義和注冊(cè)的設(shè)備驅(qū)動(dòng)可以被調(diào)用。
(3)函數(shù)。
表4 LCD控制器模塊函數(shù)
(1)模塊描述。設(shè)置framebuffer緩沖區(qū)所需的空間和定義相關(guān)底層函數(shù)。
(2)輸入、輸出。
表5 LCD控制器模塊輸入、輸出
(3)模塊接口關(guān)系。緩沖區(qū):預(yù)寫入顯示幀數(shù)據(jù),然后流向顯示器。
(4)函數(shù)。
表6 LCD控制器模塊函數(shù)
(1)模塊描述。初始化fb-info的固定、可變的參數(shù),檢查、調(diào)控顯示控制器以及顯示輸出設(shè)備信息。
(2)輸入、輸出。
表7 調(diào)控顯示信息和外接設(shè)備信息模塊輸入、輸出
(3)模塊接口關(guān)系。檢查調(diào)整顯示控制器參數(shù)var。
(4)函數(shù)。
表8 調(diào)控顯示信息和外接設(shè)備信息模塊函數(shù)
(1)模塊描述。注冊(cè)一個(gè)framebuffer驅(qū)動(dòng)。
(2)模塊接口關(guān)系。注冊(cè):注冊(cè)LCD控制器的framebuffer驅(qū)動(dòng)。
(3)函數(shù)。
表9 注冊(cè)framebuffer驅(qū)動(dòng)模塊函數(shù)
(1)模塊描述。一個(gè)I2C設(shè)備驅(qū)動(dòng)需用兩個(gè)結(jié)構(gòu)struct i2c_driver和struct i2c_client來描述。其中i2c_driver表示一個(gè)I2C設(shè)備驅(qū)動(dòng),i2c_client用于描述一個(gè)I2C設(shè)備。
(2)模塊接口關(guān)系。定義:定義設(shè)備和設(shè)備驅(qū)動(dòng)。注冊(cè):注冊(cè)外設(shè)驅(qū)動(dòng)。
(3)函數(shù)。
表10 外接設(shè)備模塊函數(shù)
(1)模塊描述。初始化并設(shè)置各種格式功能的寄存器。
(2)輸入、輸出。
表11 初始化寄存器模塊輸入、輸出
(3)模塊接口關(guān)系。初始化寄存器:初始化并設(shè)置芯片上的寄存器。
(4)函數(shù)。
表12 初始化寄存器模塊函數(shù)
(1)模塊描述。設(shè)置有關(guān)顯示輸出狀態(tài)的信息,如屏幕的顯示分辨率、畫面位置等。
(2)輸入、輸出。
表13 設(shè)置顯示輸出狀態(tài)信息模塊輸入、輸出
(3)模塊接口關(guān)系。顯示設(shè)置:根據(jù)用戶輸入信息調(diào)整輸出狀態(tài)。
(4)函數(shù)。
表14 設(shè)置顯示輸出狀態(tài)信息模塊函數(shù)
Framebuffer程序是Linux2.6.x內(nèi)核中出現(xiàn)的一種驅(qū)動(dòng)程序接口。它把一些顯示設(shè)備抽象描述成一個(gè)緩沖區(qū)域,由于Linux不像Windows那樣能夠直接調(diào)用顯卡驅(qū)動(dòng)因此framebuffer就提供了一個(gè)溝通內(nèi)存和顯卡的橋梁。用戶直接通過定義好的接口直接訪問顯卡,這樣就不需要知道底層的操作和調(diào)用。
Framebuffer在Linux內(nèi)核中一把包含于兩個(gè)文件fb.h和fbmen.c。其中fbmen.c主要提供LCD驅(qū)動(dòng)的通用文件操作接口,而fb.h中包含有很多重要的宏定義和結(jié)構(gòu)體。在結(jié)構(gòu)體中有些是我們需要注意和優(yōu)化的如:
(1)struct fb_fix_screeninfo,這個(gè)結(jié)構(gòu)體主要用來描述顯卡自身的屬性,包含標(biāo)識(shí)符、顯示數(shù)據(jù)緩存地址、顯示數(shù)據(jù)類型等,在顯卡被設(shè)定模式后創(chuàng)建,一旦系統(tǒng)開始運(yùn)行之后,該結(jié)構(gòu)體的值就不能被我們改動(dòng)。
(2)struct fb_var_screeninfo,此結(jié)構(gòu)主要用來描述顯卡的一般特性,比如虛實(shí)分辨率,以及兩者之間的offset等,也就是說,這個(gè)結(jié)構(gòu)體可以決定我們所能驅(qū)動(dòng)的外接顯示屏的尺寸。
(3)struct fb_cmap,主要用來描述設(shè)備無關(guān)的顏色映射信息??梢酝ㄟ^FBIOGETCMAP和FBIOPUTCMAP對(duì)應(yīng)的ioctl操作設(shè)定或獲取顏色映射信息。
從Linux2.6.x內(nèi)核提供的平臺(tái)驅(qū)動(dòng)機(jī)制為了方便內(nèi)核管理把設(shè)備和驅(qū)動(dòng)用platform_device和platform_driver來表示,其中platform_device表示設(shè)備而platform_driver用來注冊(cè)驅(qū)動(dòng)。設(shè)備驅(qū)動(dòng)是給用戶的程序提供系統(tǒng)調(diào)用的接口,讓用戶能夠直接通過接口來驅(qū)動(dòng)硬件設(shè)備而不用深入的了解硬件底層代碼。內(nèi)核驅(qū)動(dòng)管理機(jī)制提供了兩個(gè)函數(shù)給我們進(jìn)行注冊(cè)或者注銷我們特定平臺(tái)的LCD驅(qū)動(dòng)程序。int register_framebuffer(struct fb_info?fb_info)用于注冊(cè)該驅(qū)動(dòng);int unregister_framebuffer(struct fb_info?fb_info)則用于注銷該驅(qū)動(dòng)。幾乎所有的底層設(shè)備驅(qū)動(dòng)所要做的事情就是填充fb_inf o結(jié)構(gòu)然后利用上述的兩個(gè)函數(shù)向系統(tǒng)注冊(cè)或注銷它。
經(jīng)測(cè)試,我的VGA驅(qū)動(dòng)程序在IMX6平臺(tái)上能夠成功添加和實(shí)現(xiàn)。文中給出了VGA驅(qū)動(dòng)的整體架構(gòu)并對(duì)一些主要的工作模塊和機(jī)制進(jìn)行了詳細(xì)的講解,同時(shí)對(duì)主要模塊的設(shè)計(jì)思想和實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析討論。我在實(shí)現(xiàn)VGA模塊的開發(fā)和移植過程中通過閱讀大量的相關(guān)資料,聽取指導(dǎo)老師的一些建議,對(duì)Linux下ARM嵌入式開發(fā)積累了大量的經(jīng)驗(yàn),大大的提高了我的解決調(diào)通驅(qū)動(dòng)的能力,加深了對(duì)Android的整體架構(gòu)的理解,知識(shí)面的不足也充分暴露出來亟待改正。
[1]王振麗.Android底層開發(fā)技術(shù)實(shí)戰(zhàn)詳解——內(nèi)核、移植和驅(qū)動(dòng)[M].北京:電子工業(yè)出版社,2012,(8).
[2]陳強(qiáng).Android底層接口與驅(qū)動(dòng)開發(fā)技術(shù)詳解[M].北京:中國鐵道出版社,2012,(8).
[3]郭小梅.基于mx51的VGA驅(qū)動(dòng)開發(fā)[J].電腦編程技巧與維護(hù),2011,(08).
[4](美國)Christopher Hallinan.嵌入式Linux開發(fā)[M].北京:人民郵電出版社,2008.
[5]Robert Love,陳莉君,康華.Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)[M].北京:機(jī)械工業(yè)出版社,2011.