平頂山學(xué)院信息工程學(xué)院 張亞峰 王 冠
基于ARM的LCD顯示液晶屏驅(qū)動(dòng)的開發(fā)
平頂山學(xué)院信息工程學(xué)院張亞峰王冠
通過(guò)對(duì)LCD控制器各個(gè)子模塊的研究,并對(duì)FrameBuffer在LCD的作用進(jìn)行詳細(xì)的分析,對(duì)于硬件引腳、驅(qū)動(dòng)的端口及寄存器等進(jìn)行設(shè)置,將驅(qū)動(dòng)添加到內(nèi)核,最終實(shí)現(xiàn)了基于ARM的LCD液晶屏驅(qū)動(dòng),使內(nèi)核的啟動(dòng)信息在顯示器上顯示出來(lái)。
嵌入式系統(tǒng);LCD液晶屏驅(qū)動(dòng);Exynos 4412處理器
隨著信息技術(shù)的高速發(fā)展,人們使用的設(shè)備的智能化,與嵌入式系統(tǒng)在其中發(fā)揮的重要作用密不可分。雖然嵌入式系統(tǒng)的交互性比較強(qiáng),液晶屏作為輸出設(shè)備也被廣泛應(yīng)用,但關(guān)于液晶屏的深層次應(yīng)用開發(fā)方面的研究卻不多。本文通過(guò)對(duì)LCD顯示液晶屏驅(qū)動(dòng)的研究,加深對(duì)其認(rèn)識(shí),對(duì)其相關(guān)研究、開發(fā)材料加以補(bǔ)充。
本次開發(fā)使用的環(huán)境為ADS1.2,其具有強(qiáng)大的實(shí)時(shí)調(diào)試跟蹤功能。使用的開發(fā)平臺(tái)為Tiny4412。它是一款高性能的四核Cortex-A9核心板,處理器為Exynos 4412,具有極高的靈活性,三星Galaxy部分機(jī)型就采用該CPU設(shè)計(jì)。
Exynos4412的LCD 控制器由REGBANK、LCDCDMA、VIDPRCS、TIMEGEN組成,并有專門的端口來(lái)傳送控制信號(hào)和其它數(shù)據(jù)。
REGBANK 有許多可編程寄存器組,它們用來(lái)配置LCD 控制器的調(diào)色板存儲(chǔ)器。LCDCDMA 是一個(gè)專用DMA,并且是FIFO(First-In First-Out, 先入先出)存儲(chǔ)器,它會(huì)自動(dòng)傳送幀數(shù)據(jù)到LCD 驅(qū)動(dòng)器。TIMEGEN 由可編程邏輯組成,支持各種常見LCD 驅(qū)動(dòng)器的定時(shí)與速率界面的不同要求。TIMEGEN 模塊產(chǎn)生FRAME, VLINE, VCLK, VM 等信號(hào)。
3.1FrameBuffer的介紹
Framebuffer在LCD的驅(qū)動(dòng)實(shí)現(xiàn)中起著中間層的作用,它將內(nèi)存數(shù)據(jù)映射到進(jìn)程地址空間之后,就可以直接進(jìn)行讀寫操作,并立即反應(yīng)在屏幕上[1]。它還完成對(duì)驅(qū)動(dòng)的統(tǒng)一管理,向fbmem.c注冊(cè)是任何一個(gè)FrameBuffer驅(qū)動(dòng)在系統(tǒng)初始化時(shí)必須做的工作[2]。注冊(cè)時(shí),設(shè)備的驅(qū)動(dòng)信息保存在一個(gè)數(shù)組體中。
struct dev_message *reg[ max]; / * 定義數(shù)組 */
int reg_num; /* 設(shè)備數(shù)量 */
int reg_fb(struct dev_message * reg)
{
int x;
struct dev_thing thing;
struct dev_thing *cur;
if (reg_num >= max)
exit;
……………………
return 0;
}
3.2LCD驅(qū)動(dòng)實(shí)現(xiàn)代碼分析
3.2.1設(shè)置fb_info
(1)申請(qǐng)和釋放資源
在初始函數(shù)運(yùn)行時(shí),需要申請(qǐng)相應(yīng)的資源;在程序運(yùn)行結(jié)束時(shí),要釋放相應(yīng)的資源,以免造成系統(tǒng)的資源浪費(fèi)[3]。因此定義下面的函數(shù):
Mod_init(Exyons_init); /* 申請(qǐng)資源 */
Mod_quit(Exyons_quit); /* 釋放資源 */
定義fb_info結(jié)構(gòu)體對(duì)象:
static struct fb_info*Exyons_lcd;
分配一個(gè)fb_info結(jié)構(gòu)體,使用函數(shù)framebuffer_alloc實(shí)現(xiàn):
Exyons_lcd = framebuffer_alloc(0,NULL);
(2)可變信息設(shè)置
Exyons_lcd -> var.xres = 800;
Exyons_lcd -> var.yres = 480;
Exyons_lcd -> var.xres_virtual = 800;
Exyons_lcd -> var.yres_virtual = 480;
然后進(jìn)行紅、綠、藍(lán)三種顏色的設(shè)置和每一個(gè)像素用多少位的設(shè)置。
設(shè)置完上面的這些已經(jīng)可以實(shí)現(xiàn)LCD的顯示了。其他表示可變信息的設(shè)置根據(jù)需要進(jìn)行。
(3)顯存的分配
對(duì)顯示屏的操作,是一個(gè)存儲(chǔ)器的操作,可以直接訪問(wèn)應(yīng)用程序的內(nèi)存,它可以實(shí)現(xiàn)LCD的操作,通過(guò)應(yīng)用數(shù)據(jù)到內(nèi)存,然后LCD控制器從存儲(chǔ)器中提取數(shù)據(jù),并輸出相應(yīng)的LCD控制芯片,使實(shí)現(xiàn)LCD的控制[4]。
(4)設(shè)置其它信息
首先,設(shè)置LCD屏幕的大小,用字節(jié)來(lái)表示:
Exyons_lcd->screen_size = 800*480*32 / 8;
然后,調(diào)色板設(shè)置:
Static u32 colregs[16]; /* 代表了一個(gè)假的調(diào)色板 */
Exyons_lcd->pseudo_palette = colregs; /* 賦值操作完成設(shè)置 */
3.2.2設(shè)置LCD硬件
對(duì)LCD的硬件進(jìn)行設(shè)置要參考芯片手冊(cè)和LCD手冊(cè)進(jìn)行獲得設(shè)置值。
(1)設(shè)置用于LCD的引腳
這個(gè)寄存器可以全部用來(lái)進(jìn)行LCD顏色控制引腳。
控制LCD電源的引腳受GPGCON寄存器控制,手冊(cè)中GPGCON寄存器的描述如表1所示:

表1 GPGCON寄存器
LCD電源控制引腳設(shè)置如表2所示:

表2 電源控制引腳描述
代碼的具體實(shí)現(xiàn)如下:
int *gpccon;
int *gpdcon;
int *gpgcon; /*構(gòu)建這三個(gè)寄存器的表示指針變量*/
*gpccon = 0xaaaaaaaa;
*gpdcon = 0xaaaaaaaa;
*gpgcon | = (3<<8); /*通過(guò)這三個(gè)寄存器,設(shè)置用于控制LCD的引腳*/
(2)LCD寄存器對(duì)象的構(gòu)建
采用建立數(shù)組的方法對(duì)LCD的控制寄存器進(jìn)行一次性映射成為虛擬地址,雖然在當(dāng)下有些寄存器暫時(shí)還未被使用到,我們也把它們?cè)O(shè)置到這個(gè)數(shù)組中,這樣做可以保證所有寄存器地址的連續(xù)性,使對(duì)寄存器的操作變得方便。完成這項(xiàng)工作后,就可以通過(guò)操縱該數(shù)組元素的指針來(lái)操縱相應(yīng)的寄存器[5]。
(3)設(shè)置控制寄存器1(LCDCON1)
LINECNT:行計(jì)數(shù)器狀態(tài)位,初始值為0000000000;
CLKVAL:設(shè)置VCLK,初始值為0000000000;
MMODE:決定VM信號(hào)的觸發(fā)速率[6],初始值為0;PNRMODE:顯示模式選擇位,初始值為00;
BPPMODE:?jiǎn)蝹€(gè)像素的位數(shù)選擇,初始值為0000;
ENVID:視頻輸出和控制信號(hào)設(shè)置,初始值為0,在此置1,使信號(hào)有效。
(4)LCD垂直參數(shù)設(shè)置
參考芯片手冊(cè)和LCD手冊(cè)進(jìn)行獲得設(shè)置值:
VBPD=14;LINEVAL=239;VFPD=11;VSPW=2;
代碼實(shí)現(xiàn)設(shè)置:
Exyons_lcd_regs->lcdcon2 = (14<<24)|(239<<14)|(11<<6)|(2<<0);
(5)LCD水平參數(shù)設(shè)置
HBPD=25;HOZVAL=213;HFPD=34;HSPW=18;
代碼實(shí)現(xiàn)設(shè)置:
Exyons_lcd_regs->lcdcon3 = (37<<19)|(319<<8)|(19<<0);
Exyons_lcd_regs->lcdcon4 = 29;
(6)設(shè)置使能有效位
代碼實(shí)現(xiàn)設(shè)置:
Exyons_lcd_regs->lcdcon5 = (1<<10)|(1<<9) | (1<<8) | (1<<5) |(0<<3);
(7)顯存地址告訴LCD控制器
功能實(shí)現(xiàn)代碼:
Exyons_reg -> lcdsdr1 = (Exyons_lcd -> fix_start >> 3);
Exyons_reg->lcdsdr2=((Exyons_lcd->fix_start+800*480*4)>>1)&0x1fffff;
Exyons_lcd_regs->lcdsaddr3 =800*480/2;
3.2.3 注冊(cè)fb_info
(1)設(shè)置使能LCD
將寄存器LCDCON1的第0為設(shè)置為1:
Exyons_lcd_regs -> lcdcon1 | = (1 << 0);
(2)向上注冊(cè)fb_info結(jié)構(gòu)體對(duì)象
register_framebuffer(Exyons_lcd);
3.3添加驅(qū)動(dòng)到內(nèi)核
對(duì)于已有的驅(qū)動(dòng)模塊可以直接使用。實(shí)現(xiàn)fb_ops結(jié)構(gòu)體時(shí),有三個(gè)文件:cfbcopyarea.c、cfbfillrect.c和cfbimgblt.c已經(jīng)存在但沒有被編譯安裝,因此我們需要修改內(nèi)核drivers/video下的Makefile,重新編譯內(nèi)核,就能讓LCD正常工作[7]。操作如表1所示:

表3 Makefile文件修改內(nèi)
再次編譯內(nèi)核,重新啟動(dòng)系統(tǒng)。效果如圖1所示:

圖1 加載LCD成功后的啟動(dòng)效果
在開發(fā)的過(guò)程中,通過(guò)對(duì)Tiny4412的硬件平臺(tái)、LCD芯片手冊(cè)及CPU芯片的寄存器的研究,分析LCD驅(qū)動(dòng)內(nèi)核層次,利用FrameBuffe實(shí)現(xiàn)了對(duì)驅(qū)動(dòng)的管理和消息的分派;然后通過(guò)設(shè)置fb_ info對(duì)象和LCD硬件,進(jìn)行fb_info注冊(cè);最后添加驅(qū)動(dòng)到內(nèi)核,成功實(shí)現(xiàn)了內(nèi)核的啟動(dòng)信息在啟動(dòng)時(shí)通過(guò)LCD顯示器打印出來(lái)。
[1]劉藝柱,郭素娜.ARM嵌入式系統(tǒng)基礎(chǔ)[J].河南理工大學(xué)學(xué)報(bào),2010,29(2):229-232.
[2]賴曉晨.嵌入式系統(tǒng)編程與設(shè)計(jì)[M].北京:清華大學(xué)出版社,2009.
[3]王華祥,張淑英.深入淺出:嵌入式底層軟件開發(fā)[M].天津:天津大學(xué)出版社,2003.
[4]趙以強(qiáng).嵌入式系統(tǒng)開發(fā)之道[M].北京:人民郵電出版,2009.
[5]武斌,張一哲.嵌入式工程師必知必會(huì)[M].北京:人民郵電出版,2008.
[6]甘瑟爾.嵌入式系統(tǒng)設(shè)計(jì)的藝術(shù)(第2版)[M].北京:北京人民郵電出版社,2011.
[7]林洪貴,林金表.21天學(xué)通ARM嵌入式開發(fā)[J].莆田學(xué)院學(xué)報(bào),2007,14(5):63-65.