摘 要: Framebuffer在Linux的顯示設備上起著一個抽象的而又相當重要的作用。隨著技術的發展,諸多MCU-LCD嵌入式設備需要支持更多的上層應用二次開發及更友好的UI界面,但是由于MCU-LCD是在早期單片機中使用,對采用了Framebuffer架構的內核支持不太好。對Framebuffer自身的框架及MCU-LCD的硬件接口進行了分析和研究,根據Framebuffer的架構并結合MCU-LCD自身的特點,在比較了RGB與MCU優劣的基礎上,設計了支持Linux幀緩沖的MCU-LCD設備驅動程序結果,實現了內核Framebuffer對MCU-LCD的支持。實際應用表明,該設計對于傳統的MCU-LCD同樣也能與Framebuffer較好地結合,滿足更友好的界面開發需求。
關鍵詞: 液晶顯示;幀緩沖;驅動程序;RGB-LCD接口;MCU-LCD接口
在嵌入式的主流 LCD屏中主要支持兩大類硬件接口,一種是常見的RGB接口,另外一種是MCU接口。MCU-LCD因最早針對單片機的領域使用而得名。它在中低端手機中大量使用,其主要特點是價格便宜。MCU-LCD接口的標準術語是Interface 80,因此在很多文檔中用I80來指MCU-LCD屏[1]。
MCU-LCD屏與RGB-LCD屏主要區別在于顯存的位置不同。RGB-LCD的顯存是由系統內存充當的,因此其大小只受限于系統內存的大小,這樣 RGB-LCD可以做出較大尺寸。比如現在4.3英寸只能算入門級;而MID中7英寸、10英寸的屏都開始大量使用。但是MCU-LCD在設計之初只考慮單片機的內存較小、資源受到限制,因此把顯存內置在LCD模塊內部,然后軟件通過專門顯示命令來更新顯存。這樣一來,MCU屏往往不能做得很大,同時顯示更新速度也比RGB- LCD慢。MCU-LCD同RGB- LCD異同如表1所示。
隨著顯示技術和嵌入式技術的發展以及Linux在嵌入式系統中的普及,RGB-LCD越來越流行,在內核驅動中,有諸多RGB-LCD的驅動實例及相關文檔可以參考。由于MCU-LCD是在早期單片機中使用,因此內核對其支持不是太好,特別是采用了Framebuffer架構的內核。
1 MCU-LCD接口
MCU接口中包括I80。I80全稱為8080并口協議,是由Intel公司提出的。除8080接口協議外,還有摩托羅拉的6800接口協議,兩者的不同在于控制器,8080通過“讀使能(RE)”和“寫使能(WE)”兩條控制線進行讀寫操作。很多MCU或者LCD模塊外部接口一般采用并行方式,并行接口常見接線方式如圖1所示。
1.1 8080模式
8080模式接口信號通常有:/RES(復位線),DB0~DB7(雙向數據線),D/I(數據/指令選擇線,1:數據讀寫,0:命令讀寫),CS(片選信號線,如果有多片組合,可有多條片選信號線),/WR(MPU向LCD寫入數據控制線),/RD(MPU從LCD讀入數據控制線)。
1.2 6800模式
6800模式支持可選擇的總線寬度8/9/16/18 bit(默認為8 bit),其實際設計思想與I80一樣,主要區別就是該模式的總線控制讀寫信號組合在一個引腳(/WR)上,并增加了一個鎖存信號(E)。
2 基于Framebuffer的MCU-LCD接口驅動設計
2.1 Framebuffer架構
Framebuffer是LCD對應的一種HAL,提供了顯示設備的抽象描述,它把顯存抽象為一種設備。應用程序通過定義好的接口可以訪問顯卡,而不需要知道底層的任何操作,操作可以直接反映到顯示設備中[2]。
Framebuffer驅動程序的數據結構主要包括4個部分:fb_info、fb_ops、fb_var_screen和fb_fix_screen。fb_info結構體是幀緩沖設備中最重要的數據結構,包括了幀緩沖設備屬性和操作的完整性屬性。fb_ops結構體中的成員變量為指向底層操作的函數指針。fb_var_screen結構體記錄用戶可以修改的顯示控制器參數,fb_fix_screen記錄用戶不可修改的顯示控制器參數。Framebuffer對應的驅動及其具體實現在linux/driver/video目錄下[3]。
2.2 MCU-LCD驅動開發
MCU-LCD存在黑白、4級灰度、16級灰色、256色、4 096色的STN液晶屏蔽,同時也存在黑白、4級灰度、16級灰度、256色、64K的TFT液晶顯示屏[3-4]。不同的灰度等級或者色彩度對應不同的數據總線寬度。此處以16位數據總線寬度為例,6800的驅動與8080接口的驅動一致。
首先在/driver/video目錄下增加mcu-lcd_fb.c文件。在Linux驅動中,通過設備的名稱與驅動的名稱進行匹配,從而調用xx_probe函數,所以在mcu-lcd-fb.c中首先添加mcu-lcd-fb_probe函數。此函數用于完成對LCD設備的初始、分配顯示緩沖區及注冊Framebuffer驅動。對LCD設備的初始化工作包括對相應設備的寄存器相關配置工作的初始化和對fb_fix_screen中的固定硬件參數進行設置,同時對fb_var_screen中可變的參數進行配置。分配顯示緩沖區則需要根據液晶顯示屏的分辨率、像素點的寬度進行計算,從而得到所需要的內存空間大小。之后調用內核的API函數,注冊一個Framebuffer驅動[5-7]。
接下來聲明MCU-LCD的fb_ops。
static struct fb_op mcu_lcd_ops = {
.owner = THIS_MODULE,
.fb_check_var = mcu_lcd_check_var,
.fb_set_par = mcu_lcd_set_par,
.fb_setcolreg = mcu_lcd_setcolreg,
.fb_blank = mcu_lcd_blank,
.fb_open = mcu_lcd_open,
.fb_release = mcu_lcd_release,
.fb_copyarea = cfb_copyarea,
.fb_fillrect = cfb_fillrect,
.fb_imageblit = cfb_imageblit,
};
mcu_lcd _check_var函數確認LCD顯示屏的可變參數。mcu_lcd_set_par對硬件參數進行配置。mcu_lcd_setcolreg對LCD寄存器進行設置,設置其顯示模式和顏色數。在MCU-LCD初始化以后,只需要對LCD顯示屏中的GRAM寫入相應的數據,LCD就會根據寫入的數據顯示相關的信息。在此函數中,使用偽畫板,將需要顯示的數據放在偽畫板中進行暫時的保存。不同于RGB模式下的LCD屏,此時無需再對LCD寄存器進行相應的設置。cfb_copyarea、cfb_fillrect、cfb_imageblit則是調用Linux系統自帶的3個函數,用于對圖片顯示、矩形填充及區域拷貝進行操作。在mcu_lcd_open函數中,則是在打開Framebuffer設備文件時進行操作。由于MCU-LCD沒有時鐘線對顯示屏進行刷新操作,因此在mcu_lcd_open函數中啟動一個內核線程。設置好內核線程執行的頻率,類似于LCD屏的刷新率。當內核線程進行調度時,啟動CPU中內存地址間的DMA傳輸控制,對LCD內存寫入數據來進行刷新操作[8-10]。
Linux在嵌入式技術的發展過程中起著越來越重要的作用。Framebuffer在Linux的UI上起著抽象而又相當重要的作用。以前的諸多嵌入式設備隨著技術的發展需要進行功能及安全方面的擴展,MCU-LCD也需要支持更多的上層應用二次開發及更友好的UI界面,如QT、MiniGui等。本文通過實現支持MCU-LCD的Framebuffer驅動,從而支持了MCU-LCD對嵌入式領域更好的擴展。
在Framebuffer機制的基礎上,基于MCU-LCD這種在過去單片機時代較為通用的顯示設備,實現了嵌入式平臺下的Linux驅動程序設計,很好地解決了通用的MCU接口的LCD驅動實現。該設計為一些流行的嵌入式圖形庫如QT、MiniGUI的移植工作提供了基礎,對界面的二次開發具有良好的指導意義。
參考文獻
[1] 李瑛,魏廷存,張盛兵. 手機用TFT彩色液晶顯示驅動芯片的可配置接口電路設計[J].微電子學與計算機,2006, (5):46-49.
[2] 馮國進.嵌入式Linux驅動程序設計從入門到精通 [M].北京:清華大學出版社,2008.
[3] 張策,孫緒剛.基于Frambuffer的LCD驅動設計 [J].計算機工程與設計,2009,30(23):5372-5375.
[4] 紀寧寧,孫靈燕. S3C2410A驅動RGB接口TFT LCD的研究 [J].液晶與顯示,2008,23(1):96-98.
[5] 常赟杰,張位勇.Frambuffer的LCD驅動程序設計 [J].電腦編程技巧與維護,2009,15(4):18-19.
[6] 魯寶宏,郭磊,魏世民.嵌入式Linux平臺下LCD驅動的開發與實現[J].電子技術,2008,45(9):28-30.
[7] 蘇哲欣,劉鴻飛,薛曉.基于嵌入式Linux的LCD驅動分析與實現[J].工業控制計算機,2009,22(2):29-30.
[8] 孫俊喜.LCD驅動電路、驅動程序設計及典型應用[M].北京:人民郵電出版社,2009.
[9] 李春燕.Linux內核的嵌入式系統裁減以及LCD驅動的實現[J].電腦知識與技術,2008,1(1) :29-37.
[10]張伽偉,周安棟,羅勇. ARM11嵌入式系統Linux下 LCD的驅動設計[J].液晶與顯示,2011,26(5):660-664.