一種圖形顯示驅動的設計和實現(xiàn)
出處:趙 鑫, 李 曦 發(fā)布于:2011-07-19 22:23:03
在嵌入式系統(tǒng)這個IT產業(yè)的新領域,Linux 以其所具備的穩(wěn)定、高效、易定制、易裁減、硬件支持廣泛的特點,結合其、源碼開放的特征。使得Linux在嵌入式操作系統(tǒng)中的地位越來越重要。越來越多的嵌入式系統(tǒng),包括 PDA、機頂盒、WAP 手機等等系統(tǒng)均要求提供全功能的 Web 瀏覽器。這包括 HTML 的支持、JavaScript 的支持,甚至包括 Java 虛擬機的支持。而這一切都要求有一個高性能、高可靠的 GUI 的支持。這些系統(tǒng)一般不希望建立在龐大累贅的、非常消耗系統(tǒng)資源的操作系統(tǒng)和 GUI 之上,比如 Windows 或 X Window.但是,在出現(xiàn) Linux 系統(tǒng)之后 GUI 仍然是一個問題。關鍵是 X Window 太過龐大和臃腫。uClinux是專為無存儲器管理單元的處理器定制的嵌入式Linux操作系統(tǒng)。其內嵌的Microwindow為嵌入式系統(tǒng)圖形界面提供了良好的支持。
本文詳細闡述了基于μClinux 操作系統(tǒng)的圖形應用的軟件結構,并在此基礎上介紹了圖形顯示的底層硬件驅動技術,系統(tǒng)地給出了實現(xiàn)驅動的數(shù)據(jù)結構和算法。
1 μClinux簡介
μClinux是一個完全符合GNU/GPL公約的操作系統(tǒng),完全開放源代碼,現(xiàn)在由Line公司支持維護。μClinux的發(fā)音是you-see-linux,它的名字來自于希臘字母μ和英文大寫字母C結合。μ代表"微小"之意,字母C代表"控制器",所以從字面上就可以看出它的含義,即"微控制領域中的Linux系統(tǒng)".
μClinux由Linux2.0內核發(fā)展而來,它繼承了Linux的主要特點,并針對微控制領域中不具有MMU(存儲管理單元)的處理器做了修改。μClinux重寫了內核中大部分的二進制代碼和源代碼,因此內核比Linux2.0小很多,但它同時卻保留了Linux操作系統(tǒng)的穩(wěn)定性以及出色地支持多種文件系統(tǒng)的特性。?滋Clinux已被廣泛應用于嵌入式系統(tǒng)中,本文將基于該操作系統(tǒng)研究圖形硬件驅動。
2 圖形系統(tǒng)的體系結構
嵌入式系統(tǒng)的顯示輸出分為圖形輸出和純文本輸出二部分。μClinux操作系統(tǒng)中控制臺(Console)處理純文本的輸出,而幀緩沖(Frame Buffer)負責圖形信息的輸出。
μClinux操作系統(tǒng)的圖形系統(tǒng)從軟件結構角度可以分為如圖1所示的三層。

層是圖形硬件驅動程序,用來操作圖形硬件設備。μClinux系統(tǒng)中對圖形硬件設備的操作通過標準化的調用接口映射到該層實施。
中間層是GUI圖形引擎,該層把層提供的基本圖形輸出操作結合起來完成較為復雜的圖形輸出。為該層設計的GUI圖形引擎已經有成熟的產品,如國內的MiniGUI、國外的MicroWindows以及Embedded QT等。
層是圖形應用程序層,各種圖形應用程序都在該層實現(xiàn)。應用程序調用中間層的圖形引擎完成各種復雜圖形效果的輸出。
本文研究的對象是圖形系統(tǒng)層的硬件驅動。
3 圖形硬件驅動
3.1 μClinux設備驅動簡介
μClinux將設備分為字符設備、塊設備和網絡設備三大類。圖形顯示硬件設備屬于字符設備。
μClinux驅動程序的基本結構和Linux驅動程序的結構類似。不同的是:Linux使用模塊化(module)的方式處理設備驅動,可以根據(jù)需求將所需驅動加載到系統(tǒng)內核中。μClinux雖然也支持模塊化的處理方式,但是,由于存儲空間的限制以及嵌入式系統(tǒng)具有針對性的功能要求,所以,通常在編譯內核時便放棄了對模塊化的支持而采用將驅動直接編譯進內核的方式安裝驅動。
μClinux的設備驅動程序和文件系統(tǒng)緊密地結合在一起,各種設備以文件的形式存放在/dev目錄下,稱為設備文件。用戶程序使用open( )、close( )、read( )、write( )等標準調用函數(shù)操作硬件設備。內核通過file_operations結構調用驅動程序中的函數(shù)。這是一個通用的文件操作函數(shù)指針的集合,包含了?滋Clinux提供的全部文件系統(tǒng)操作函數(shù)。在硬件驅動程序中只需實現(xiàn)該硬件所需的部分函數(shù),而將其他的函數(shù)指針置空。
3.2 圖形硬件驅動的研究與實現(xiàn)
3.2.1 圖形硬件驅動
圖形硬件的驅動在滋Clinux中是比較復雜的驅動,同它相關的函數(shù)及文件分為二類。
?。?)Frame Buffer驅動程序。驅動程序的代碼存放在fbmem.c文件中。Frame Buffer為顯示設備提供一個通用接口,它是將顯存抽象后的設備。它通過地址映射允許上層用戶在圖形模式下對顯示緩沖區(qū)進行讀寫。Frame Buffer的存在使用戶不必關心物理顯存的位置、換頁機制等細節(jié)問題,同時簡化了用戶程序代碼在不同硬件平臺間的移植。
(2)Frmae Buffer的輔助函數(shù)。這些函數(shù)聲明在fb.h中。不同的嵌入式系統(tǒng)中,圖形顯示硬件不完全相同,硬件獨有的狀態(tài)數(shù)據(jù)由這些輔助函數(shù)記錄并修改。Frame Buffer調用輔助函數(shù)控制顯示硬件設備。
下面從這二方面探討圖形硬件驅動的實現(xiàn)。
3.2.2 Frame Buffer驅動
Frame Buffer的驅動代碼存放在fbmem.c中,該文件早出現(xiàn)在Linux-1.3.94內核版本中。其中的數(shù)據(jù)結構是包含操作Frame Buffer函數(shù)的指針集合struct file_operations fb_fops.
static struct file_operations fb_fops={
NULL, //lseek
fb_read, //read
fb_write, //write
NULL, //readdir
NULL, //select
fb_ioctl, //ioctl
fb_mmap, //mmap
fb_open, //open
fb_release, //release
NULL //fsync
};
Frame Buffer設備文件的特征決定了其只需要實現(xiàn)文件操作函數(shù)中的部分調用,如:fb_read、fb_write、fb_mmap等。
由于處理器不支持MMU,μClinux操作系統(tǒng)對內存的管理不同于標準的Linux.在沒有MMU的嵌入式系統(tǒng)中,顯存的空間是獨立且固定的,μClinux操作系統(tǒng)可以線性地訪問顯存空間?;诖?,?滋Clinux中的fb_mmap可以修改成如下代碼:
static int fb_mmap(struct inode*inode,struct file*file,
struct vm_area_struct*vma) {
struct fb_ops*fb=registered_fb[ GET_FB_IDX(inode->i_rdev)];
struct fb_fix_screeninfo fix;
if(!fb)
return -ENODEV;
fb->fb_get_fix(&fix,PROC_CONSOLE( ));
vma->vm_start=fix.smem_start+vma->vm_offset;
return 0;
}
由于μClinux直接通過地址總線訪問顯存空間,所以地址映射被處理成直接訪問內存地址的方式。
fb_open、fb_write、fb_read等函數(shù)完成驅動Frame Buffer所必須的另外幾個操作,函數(shù)fb_ioctl則用來調用輔助函數(shù)記錄和修改硬件狀態(tài)數(shù)據(jù)。這些函數(shù)只需做微小的修改便可以滿足嵌入式系統(tǒng)圖形顯示的需要。限于篇幅,在此不作詳細說明。
3.2.3 Frame Buffer的輔助函數(shù)
Frame Buffer調用顯示驅動的輔助函數(shù)記錄與修改顯示硬件狀態(tài)數(shù)據(jù)。由于不同顯示硬件設備的工作方式不同,所以需要為它們定制特別的輔助函數(shù)。Frame Buffer的實現(xiàn)離不開輔助函數(shù),因此include/linux/fb.h初和fbmem.c一起出現(xiàn)在Linux-1.3.94內核版本中。fb.h中聲明了輔助函數(shù)的接口,函數(shù)實現(xiàn)代碼則需要根據(jù)具體的硬件結構編寫并保存在文件xxxfb.c中。
fb.h文件中定義了記錄圖形硬件固有狀態(tài)參數(shù)的struct fb_fix_screeninfo和記錄圖形硬件可變參數(shù)的struct fb_var_screeninfo,同時聲明了操作這二組數(shù)據(jù)的函數(shù)指針集合struct fb_ops:
struct fb_ops {
//讀取固有參數(shù)
int (*fb_get_fix) (struct fb_fix_screeninfo*,int);
//讀取可變參數(shù)
int (*fb_get_var) (struct fb_var_screeninfo*,int);
//設置可變參數(shù)
int (*fb_set_var) (struct fb_var_screeninfo*,int);
//讀取color map
int (*fb_get_cmap) (struct fb_cmap*,int,int);
//設置color map
int (*fb_set_cmap) (struct fb_cmap*,int,int);
//平面顯示函數(shù)
int (*fb_pan_display) (struct fb_var_screeninfo*,int);
int (*fb_ioctl)(struct inode*,struct file*,unsigned int,
unsigned long,int);
};
在xxxfb.c文件中必須聲明這樣兩個變量:
static struct fb_fix_screeninfo xxx_fb_fix;/*硬件固有參數(shù)*/
static struct fb_var_screeninfo xxx_fb_var;/*硬件可變參數(shù)*/
fb_ops中的函數(shù)指針在xxxfb.c文件中完成函數(shù)代碼:
static struct fb_ops xxxfb_ops={
xxxfb_get_fix,
xxxfb_get_var,
xxxfb_set_var,
xxxfb_get_cmap,
xxxfb_set_cmap,
xxxfb_pan_display,
xxxfb_ioctl
};
結合顯示硬件結構特征實現(xiàn)這幾個函數(shù),其中關鍵的函數(shù)有xxxfb_get_fix、xxxfb_set_var和xxxfb_get_var.這三個函數(shù)分別對xxx_fb_fix和xxx_fb_var中的參數(shù)進行讀取和設置。
以xxxfb_get_fix為例,該函數(shù)從xxx_fb_fix中讀取硬件的固有狀態(tài)參數(shù)。有二種實現(xiàn)方法:(1)從xxx_fb_fix中逐個讀取需要的參數(shù)。對具體的硬件,fb_fix_screeninfo中只有部分數(shù)據(jù)是需要被處理的,因此只需要讀取有效數(shù)據(jù)。(2)調用系統(tǒng)的memcpy( )函數(shù)將xxx_fb_fix完全拷貝出來。這種方法方便,但對嵌入式系統(tǒng)來說是以加大存儲空間的開銷為代價的。
另外二個函數(shù)xxxfb_get_var和xxxfb_set_var也可以做類似的處理。
在xxxfb.c文件中,啟動顯示硬件的函數(shù)是xxxfb_init( )。該函數(shù)將當前的顯示硬件注冊到系統(tǒng)中供Frame buffer調用,同時還完成對xxx_fb_fix的賦值。具體代碼如下:
void xxxfb_init(void)
{
……
/*硬件的固有數(shù)據(jù)是固定的,因此在這里對xxx_fb_fix進行賦值*/
……
//將顯示硬件注冊到系統(tǒng)中
err=register_framebuffer(&fb_info.gen.info);
if (err<0)
return err;
……
return mem_start;//返回顯存起始地址
}
xxxfb_init( )函數(shù)被fbmem.c文件的fb_open( )函數(shù)調用。由于圖形硬件的多樣性,fb_open( )函數(shù)根據(jù)具體硬件信息選擇xxxfb_init( )啟動輔助函數(shù)。
μClinux中線性的顯存訪問是實現(xiàn)圖形顯示驅動首先要注意的問題,處理好上面提到的函數(shù)和數(shù)據(jù)就可以為特定嵌入式系統(tǒng)的顯示設備開發(fā)出合適的輔助函數(shù)。
3.2.4 安裝驅動
下面介紹將顯示驅動安裝進內核的步驟。
?。?)圖形顯示硬件屬字符設備,因此將fbme.c文件保存到目錄/linux-2.0/driver/char/中。
?。?)將圖形設備加入到的Makefile文件中。
?。?)在/linux/init/main.c文件中添加驅動的啟動函數(shù)fbmem_init( )。
?。?)修改編譯選項文件,在/linux/arm/armnommu/config.in文件中加入:
bool′ framebuffer support′ CONFIG_FB_XXX
?。?)為文件系統(tǒng)的open( )調用提供設備文件名。在/vendors/<VENDOR>/<BOARD>/Makefile的'DEVICES='中,加入'xxxfb,c,29,0'作為顯示設備驅動的入口。其中29是主設備號,從設備號可以根據(jù)需要改變,這里將它設為0.
?。?)使用make工具重新編譯內核,就可將圖形顯示的驅動編譯進μClinux內核。
以上六步將顯示硬件驅動安裝到μClinux的內核中,在此基礎上選用合適的圖形包就可以在嵌入式系統(tǒng)中方便地開發(fā)圖形應用程序。
4 結束語
目前越來越多嵌入式系統(tǒng)要求圖形顯示界面,特別是在一些工業(yè)控制領域。本系統(tǒng)已經成功運用于色譜儀工作站上。其友好的人機界面大大降低了儀表操作難度,簡化了操作流程,提高了生產效率。
版權與免責聲明
凡本網注明“出處:維庫電子市場網”的所有作品,版權均屬于維庫電子市場網,轉載請必須注明維庫電子市場網,http://www.hbjingang.com,違反者本網將追究相關法律責任。
本網轉載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網站或個人從本網轉載時,必須保留本網注明的作品出處,并自負版權等法律責任。
如涉及作品內容、版權等問題,請在作品發(fā)表之日起一周內與本網聯(lián)系,否則視為放棄相關權利。
- ARM技術架構與應用開發(fā)實踐指南2026/1/6 10:40:19
- 嵌入式實時操作系統(tǒng)(RTOS)選型與移植技術指南2025/12/31 10:42:31
- 工業(yè)嵌入式系統(tǒng):通信接口技術選型與抗干擾設計實踐2025/12/15 14:36:53
- 深入解析嵌入式 OPENAMP 框架:開啟異核通信新時代2025/7/22 16:27:29
- 一文快速了解OPENWRT基礎知識2025/7/14 16:59:04









