歡迎您光臨本站 登入註冊首頁

Linux液晶屏驅動開發

admin @ 2014-03-25 , reply:0

概述

   隨著高性能嵌入式處理器的普及和硬體成本的不斷降低,尤其是ARM系列處理器的推出,嵌入式系統的功能越來越強。單色LCD也因為色彩單調,存儲信息小,處理速度慢而不能符合……

    隨著高性能嵌入式處理器的普及和硬體成本的不斷降低,尤其是ARM 系列處理器的推出,嵌入式系統的功能越來越強。單色LCD也因為色彩單調,存儲信息小,處理速度慢而不能符合人們的需求。在多媒體應用的推動下,彩色LCD越來越多地應用到了嵌入式系統中 如新一代手機和掌上電腦多採用TFT顯示器件,該顯示器件支持彩色圖形界面和視頻媒體播放。Linux作為開放源代碼的操作系統也在市場中佔據了一席之地。由於Linux成本低廉,源代碼開放,因此成為國內外廠商極力發展的操作系統。在應用需求的推動下,Linux下也出現了許多圖形界面軟體包,如MiniGUI、Trolletech公司的Embedded QT等,其圖形界面及開發工具與Windows CE不相上下。在圖形軟體包的開發和移植工作中都牽涉到底層LCD的驅動問題。筆者有幸參與了Linux操作系統下LCD部分的開發,其主要功能是點亮液晶屏,將在攝像頭上採集的BMP圖片在液晶屏上顯示並將BMP 格式壓縮成JPEG格式,使得存儲量減少。因此筆者就在開發過程中遇到的問題一一闡述。

背景知識
    在切入正題之前,先來了解在做驅動過程中需要預先知道的知識。
1 硬體平台
    MC9328MX1(以下簡稱MX1)是Motorola 公司基於ARM核心的第一款MCU,主要面向高端嵌入式應用。內部採用ARM920T內核,並集成了SDRAM/Flash、LCD,USB、藍牙.多媒體快閃記憶體卡(MMC/SD、Memory Stick)和CMOS攝像頭等控制器。
    LCD控制器的功能是產生顯示驅動信號,驅動LCD顯示器。用戶只需要通過讀寫一系列的寄存器,完成配製和顯示控制。MX1中的LCD控制器可支持單色/彩色LCD 顯示器。支持彩色TFT時,可提供4/8/12/16位顏色模式,其中16位顏色模式下可以顯示64k種顏色。配置LCD控制器重要的一步是指定顯示緩衝區,顯示的內容就是從緩衝區中讀出的,其大小由屏幕解析度和顯示顏色數決定。在本例中,採用KYocera 公司的KCS057QV1AJ液晶屏,在240×320解析度下可提供8位彩色顯示,即最大256色點陣圖。

2.Linux下的設備驅動
    在Linux操作系統下有兩類主要的設備文件類型,一種是字元設備,另一種是塊設備。字元設備和塊設備的主要區別是在對字元設備發出讀/寫請求時,實際的硬體I/O一般就緊接著發生了,塊設備則不然,它利用一塊系統內存作緩衝區,當用戶進程對設備請求讀/寫時,它首先察看緩衝區的內容,如果緩衝區的數據能滿足用戶的要求,就返回請求的數據,如果不能,就調用請求函數來進行實際的I/O操作。
    Linux的設備管理是和文件系統解密結合的,各種設備都以文件的形式存放在/dev目錄下,稱為設備文件。應用程序可以打開、關閉和讀寫這些設備文件,完成對設備的操作,就像操作普通的數據文件一樣。為了管理這些設備,系統為設備編了號,每個設備號又分為主設備號和次設備號。主設備號用來區分不同種類的設備,而次設備號標識使用同一個設備驅動程序的不同的硬體設備,比如有兩個軟盤,就可以用從設備號來區分它們。設備文件的主設備號必須與設備驅動程序在登記時申請的主設備號一致,否則用戶進程將無法訪問到驅動程序。幀緩衝設備為標準字元設備,主設備號為29,次設備號則從0到31。

3.Linux的幀緩衝設備
    幀緩衝區是出現在Linux 2.2.xx及以後版本內核當中的一種驅動程序介面,這種介面將顯示設備抽象為幀緩衝區設備區。它允許上層應用程序在圖形模式下直接對顯示緩衝區進行讀寫操作。這種操作是抽象的、統一的,用戶不必關心物理顯存的位置、換頁機制等具體細節。這些都由Framebufer設備驅動來完成。幀緩衝設備對應的設備文件為/dev/fb*,如果系統有多個顯示卡,Linux下還可支持多個幀緩衝設備,最多可達32個,分別為/dev/fb0到/dev/fb31,而/dev/fb則為當前預設的幀緩衝設備,通常指向/dev/fb0。當然在嵌入式系統中支持一個顯示設備就夠了。在使用Framebufer時,Linux是將顯卡置於圖形模式下的.在應用程序中,一般通過將Frame-Buffer設備映射到進程地址空間的方式使用,對於幀緩衝來說,可以把它看成是一段內存,用於讀寫內存的函數均可對這段地址進行讀寫,只不過這段內存被專門用於放置要在LCD上顯示的內容,其目的就是通過配置LCDC寄存器在一段指定內存與LCD 之間建立一個自動傳輸的通道。這樣,任何程序只要修改這段內存中的數據,就可以改變LCD 上的顯示內容。
    FrameBuffer設備驅動基於linux/include/linux/fb.h和linux/drivers/video/fbmem.c這兩個文件,下面就詳細分析這兩個文件。
    首先分析linux/include/linux/fb.h文件,幾乎主要的結構都是在這個文件中定義的。這些結構包括:
◆ fb_var_screeninfo 這個結構描述了顯示卡的特性,記錄了幀緩衝設備和指定顯示模式的可修改信息。其中變數xres定義了屏幕一行所佔的像素數,yres定義了屏幕一列所佔的像素數,bits_per_pixel定義了每個像素用多少個位來表示。
◆ fb_fix_screeninfon 這個結構在顯卡被設定模式后創建,它描述顯示卡的屬性,並且系統運行時不能被修改;比如FrameBuffer內存的起始地址。
◆ struct fb_info Linux為幀緩衝設備定義的驅動層介面。它不僅包含了底層函數,而且還有記錄設備狀態的數據。每個幀緩衝設備都與一個fb_info結構相對應。其中成員變數modename為設備名稱,fontname為顯示字體,fbops為指向底層操作的函數的指針。
◆ fb_cmap描述設備無關的顏色映射信息。可以通過FBIOGETCMAP 和FBIOPUTCMAP 對應的ioctl操作設定或獲取顏色映射信息。然後分析fbmem.h文件。
    幀緩衝設備屬於字元設備,採用“文件層-驅動層”的介面方式。在文件層為之定義了以下數據結構:
Static struct file_operations
fb_fops={
ower:THIS_MODULE,
read:fb_read,/*讀操作*/
write:fb_write,/*寫操作*/
ioctl:fb_ioctl,/*I/O操作*/
mmap:fb_mmap,/*映射操作*/
open:fb_open,/*打開操作*/
release:fb_release,/*關閉操作*/}
    其成員函數都在linux/driver/video/fbmem.c中定義,其中的函數對具體的硬體進行操作,對寄存器進行設置,對顯示緩衝進行映射。
    對於/dev/fb,對顯示設備的操作主要有以下幾種:
◆ 讀/寫(read/write)/dev/fb 相當於讀/寫屏幕緩衝區。
◆ 映射(map)操作 由於Linux工作在保護模式和每個應用程序里都有自己的虛擬地址空間,在應用程序中是不能直接訪問物理緩衝區地址的。因此,Linux在文件操作file_operations結構中提供了mmap函數,可將文件的內容映射到用戶空間。對於幀緩衝設備,則可通過映射操作,可將屏幕緩衝區的物理地址映射到用戶空間的一段虛擬地址中,之後用戶就可以通過讀寫這段虛擬地址訪問屏幕緩衝區,在屏幕上繪圖。
◆ I/O控制 對於幀緩衝設備,對設備文件的ioctl操作可讀取/設置顯示設備及屏幕的參數,如解析度、顯示顏色數和屏幕大小等。ioctl的操作是由底層的驅動程序來完成的。
    在應用程序中,操作/dev/fb的一般步驟為首先打開/dev/fb設備文件,然後用ioctl操作取得當前顯示屏幕的參數,如屏幕解析度,每個像素點的比特數,根據屏幕參數可計算屏幕緩衝區的大小。接下來,將屏幕緩衝區映射到用戶空間。最後,映射后就可以直接讀寫屏幕緩衝區,進行繪圖和圖片顯示了。典型程序段如下:
#include
int main(){
int fb=0;
struct fb_var_screeninfo vinfo;
struct fb_flx_screeninfo finfo;
long int screensize=0;
fb=open("/dev/fbO",O_RDWR);
/*打開設備文件*/
inctl(fb,FBIOGET_FSCREENINFO,&finfo);
/*取得屏幕相關參數*/
inctl(fb,FBIOT_VSCREENINFO,&vinfo);
ioctl(current_vt,KDSETMODE,KD_GRAPHICS);//console就進入了圖形模式,不顯示文本游標也不回顯
/*計算屏幕緩衝區大小*/
screensize=vinfo.xres*vinfo.
yres*vinfo.bits_per_pixel/8;
/*映射屏幕緩衝區到用戶地址空間*/
fop=(char*)mmap(0,screensize,
PROT_READ|PROT_WRITE,
MAP_SHARED,fb,0);
/*下面可通過fop指針讀寫緩衝區*/
……)
    由於準備在LCD 上顯示一幅256色BMP圖片,關於BMP 圖片方面的知識請見相關鏈接。

4.幀緩衝驅動的縮寫
    了解了上述知識后,在編寫驅動的時候就簡單多了。源程序共將程序分為初始化幀緩衝模塊fb_init(),調色板獲取色彩模塊get_cmap(),圖片顯示模塊display_bmp(),main函數4個函數。其中調色板獲取色彩模塊的功能是從文件中獲得圖像顯示色彩,重置系統調色板,使圖像能正確的顯示色彩。
static void ge_cmap(struct
fb_cmap *cmap,int fb){
memset(cmap,0,sizeof
(struct fb_cmap));//為cmap分配內存
cmap->start=0;
cmap->len=256;
cmap->red=calloc(256,sizeof(_u16));
cmap->green=calloc(256,sizeof(_u16));
cmap->blue=calloc(256,sizeof(_u16));
ioctl(fb,FBIOGETCMAP,cmap);}
    圖片顯示函數部分重要代碼為:
lseek(fp_bmp,pos+1024,SEEK_SET);//將當前文件指針定位在BMP圖形數據區開始讀取數據信息
read(fp_bmp,tp,76800);//320*240
for(size=0;size<76800;size++)
*(lcd_base+size)=*(tp+76800-size);//數據是從下往上放置
free(tp);
    在主函數中,建立一個進程調用圖片顯示函數
pid_t pid;
pid=fork();
if(fork>1){if(fb_init()) break;
memset(lcd_bas,0x3f,320*240);
display_bmp("/tmp/cat01.bmp",fb);}
……}
    至此LCD的驅動程序就編寫完成了,經過調試,編譯鏈接,然後用串口下載到實驗板上,一幅256色BMP圖片就可以出現在液晶屏幕上了。

5.應用價值
    液晶屏點亮了,這只是第一步,我們可以在此基礎上進一步進行應用程序的開發,比如筆者將此應用在一個視頻監控系統中。在這個視頻監控系統中,圖像處理占很大的比重,基本的圖像處理構成如下:
◆ 圖像採集模塊圖像採集模塊需要兩種裝置,一種是將光信號轉換成電信號的物理器件,如攝像機;另一種是能夠將模擬電信號轉換成數字信號的器件,如圖像採集卡。
◆ 圖像處理模塊對圖像的處理一般可用演算法的形式描述,但是對於特殊的問題需要特殊的解決方法,圖像處理模塊中不但包含了對圖像的一般處理方法,也包括一些特殊的演算法處理。
◆ 圖像顯示模塊對於採集得到的圖像,經過處理以後,最終需要顯示給用戶看。在系統的實時採集部分中,需要對展開的圖像進行滾屏顯示:在圖像編輯部分中,需要瀏覽所要拼接的圖像。所以圖像顯示對於系統來說非常重要。
◆ 圖像儲存模塊由於圖像中包含有大量的信息,並且由於系統所採用8位真彩色格式,因此需要大量的空間。因此,在本系統中需要大容量和快速的圖像存儲器。
◆ 圖像通信模塊隨著網路的建設和發展,圖像通信傳輸也得到極大的重視。另外,圖像傳輸可以使不同的系統共享圖像數據資源,快速地將結果反映到遠處系統,所以極大推動了圖像在各個方面的應用。
    在這五步中,首先在點亮液晶屏之後,才能做下一步工作。比如說筆者能夠在LCD顯示一幅圖畫,但由於這幅圖是BMP格式的,它的存儲量非常驚人,一幅320×240的BMP格式就有320×240×8/8=76800,也就是77KB,這對於系統資源相對短缺的嵌入式設備來說佔用系統RAM 太大了,因此我們就要將BMP格式的圖片壓縮成佔用系統資源少的圖片格式,比如JPEG 格式或PNG格式,可以有效地減少存儲量。
    由於篇幅所限,不可能把完整的源代碼均做一番解釋,但主要的過程就是這些,在此拋磚引玉。隨著液晶屏在嵌入式設備中的用途越來越廣,會有很大的空間值得我們去研究。

相關鏈接
BMP文件格式介紹
    BMP文件分四部分,包括點陣圖文件頭和點陣圖信息頭、彩色表、點陣圖數據。在點陣圖文件頭中包括文件類型、文件大小和文件存放位置等。點陣圖信息頭包含點陣圖的大小、壓縮類型和顏色格式。彩色表包含的元素與點陣圖所具有的顏色數目相同,像素顏色用結構RGBQUAD 來表示:
typedef struct tagRGBQUAD{
BYTE rgbBlue;//指定藍色強度
BYTE rgbGreen;//指定綠色強度
BYTE rgbRed;//指定紅色強度
BYTE rgbReserved;保留,設為0
}RGBQUAD;
    緊跟在彩色表后的是圖像數據,圖像每一掃描行有連續的位元組組成,掃描行由底向上存儲,陣列中第一位元組為左下角像素,最後一位元組為右上角像素。這一點在編程時會用到。


[admin via 研發互助社區 ] Linux液晶屏驅動開發已經有2123次圍觀

http://cocdig.com/docs/show-post-42184.html