嵌入式系統中LCD驅動的實現原理

2022-12-19 08:57:02 字數 5193 閱讀 5596

作者:四川大學楊顯強田遠富日期:2005-8-1**:本網

字元大小:【大】【中】【小】

結合三星公司arm9系列嵌入式處理器s3c2410,講解如何進行lcd驅動程式模組化程式設計及如何將驅動程式靜態載入進系統核心。

lcd(液晶顯示)模組滿足了嵌入式系統日益提高的要求,它可以顯示漢字、字元和圖形,同時還具有低壓、低功耗、體積小、重量輕和超薄等很多優點。隨著嵌入式系統的應用越來越廣泛,功能也越來越強大,對系統中的人機介面的要求也越來越高,在應用需求的驅使下,許多任務作在linux下的圖形介面軟體包的開發和移植工作中都涉及到底層lcd驅動的開發問題。因此在嵌入式系統中開發lcd驅動得以廣泛運用。

本文以三星公司arm9核心晶元s3c2410的lcd介面為基礎,介紹了在linux平台上開發嵌入式lcd驅動程式的一般方法。

本文硬體採用三星公司的s3c2410晶元的開發板,軟體採用linux2.4.19平台,編譯器為arm-linux-gcc的交叉編譯器,使用640×480解析度的tft彩色lcd,通過對其linux驅動程式進行改寫和除錯,成功地實現了對該種屏的驅動和顯示。

嵌入式驅動的概念

裝置驅動程式是作業系統核心和機器硬體之間的介面,裝置驅動程式為應用程式遮蔽了硬體的細節,這樣在應用程式看來,硬體裝置只是乙個裝置檔案,應用程式可以像操作普通檔案一樣對硬體裝置進行操作。裝置驅動程式是核心的一部分,它主要完成的功能有:對裝置進行初始化和釋放;把資料從核心傳送到硬體和從硬體讀取資料;讀取應用程式傳送給裝置檔案的資料、回送應用程式請求的資料以及檢測和處理裝置出現的錯誤。

linux將裝置分為最基本的兩大類:一類是字元裝置,另一類是塊裝置。字元裝置和塊裝置的主要區別是:

在對字元裝置發出讀/寫請求時,實際的硬體i/o一般就緊接著發生了。字元裝置以單個位元組為單位進行順序讀寫操作,通常不使用緩衝技術;塊裝置則是以固定大小的資料塊進行儲存和讀寫的,如硬碟、軟盤等,並利用一塊系統記憶體作為緩衝區。為提高效率,系統對於塊裝置的讀寫提供了快取機制,由於涉及緩衝區管理、排程和同步等問題,實現起來比字元裝置複雜得多。

lcd是以字元裝置方式加以訪問和管理的,linux把顯示驅動看做字元裝置,把要顯示的資料一位元組一位元組地送往lcd驅動器。

linux的裝置管理是和檔案系統緊密結合的,各種裝置都以檔案的形式存放在/dev目錄下,稱為裝置檔案。應用程式可以開啟、關閉和讀寫這些裝置檔案,完成對裝置的操作,就像操作普通的資料檔案一樣。為了管理這些裝置,系統為裝置編了號,每個裝置號又分為主裝置號和次裝置號。

主裝置號用來區分不同種類的裝置,而次裝置號用來區分同一型別的多個裝置。對於常用裝置,linux有約定俗成的編號,如硬碟的主裝置號是3。linux為所有的裝置檔案都提供了統一的操作函式介面,方法是使用資料結構struct file_operations。

這個資料結構中包括許多操作函式的指標,如open()、close()、read()和write()等,但由於外設的種類較多,操作方式各不相同。struct file_operations結構體中的成員為一系列的介面函式,如用於讀/寫的read/write函式和用於控制的ioctl等。開啟乙個檔案就是呼叫這個檔案file_operations中的open操作。

不同型別的檔案有不同的file_operations成員函式,如普通的磁碟資料檔案,介面函式完成磁碟資料塊讀寫操作;而對於各種裝置檔案,則最終呼叫各自驅動程式中的i/o函式進行具體裝置的操作。這樣,應用程式根本不必考慮操作的是裝置還是普通檔案,可一律當作檔案處理,具有非常清晰統一的i/o介面。所以file_operations是檔案層次的i/o介面。

lcd控制器

lcd控制器的功能是顯示驅動訊號,進而驅動lcd。使用者只需要通過讀寫一系列的暫存器,完成配置和顯示驅動。在驅動lcd設計的過程中首要的是配置lcd控制器,而在配置lcd控制器中最重要的一步則是幀緩衝區(framebuffer)的指定。

使用者所要顯示的內容皆是從緩衝區中讀出,從而顯示到螢幕上的。幀緩衝區的大小由螢幕的解析度和顯示色彩數決定。驅動幀緩衝的實現是整個驅動開發過程的重點。

s3c2410中的lcd控制器可支援stn和tft兩種液晶。對於stn液晶平板,該lcd控制器可支援4位雙掃瞄、4位單掃瞄和8位單掃瞄三種顯示型別,支援4級和16級灰度級單色顯示模式,支援256色和4096色顯示,可接多種解析度的lcd,例如640×480、320×240和160×160等,在256色顯示模式時,最大可支援4096×1024、2048×2048和1024×4096顯示。tft液晶平板可支援1-2-4-8bpp(bitsperpixel)調色盤顯示模式和16bpp非調色盤真彩顯示。

幀緩衝區是出現在及以後版本核心當中的一種驅動程式介面,這種介面將顯示裝置抽象為幀緩衝區裝置區。幀緩衝區為影象硬體裝置提供了一種抽象化處理,它代表了一些**硬體裝置,允許應用軟體通過定義明確的介面來訪問影象硬體裝置。這樣軟體無須了解任何涉及硬體底層驅動的東西(如硬體暫存器)。

它允許上層應用程式在圖形模式下直接對顯示緩衝區進行讀寫和i/o控制等操作。通過專門的裝置節點可對該裝置進行訪問,如/dev/fb*。使用者可以將它看成是顯示記憶體的乙個映像,將其對映到程序位址空間之後,就可以進行讀寫操作,而讀寫操作可

以反映到lcd。

幀緩衝裝置對應的裝置檔案是/dev/fb*。如果系統有多個顯示卡,linux還支援多個幀緩衝裝置,最多可達32個,即/dev/fb0~/dev/fb31。而/dev/fb則指向當前的幀緩衝裝置,通常情況下,預設的幀緩衝裝置為/dev/fb0。

幀緩衝裝置也屬於字元裝置,採用「檔案層-驅動層」的介面方式。在檔案層為之定義了以下資料結構。

static struct file_operations fb_fops=

其成員函式都在linux/driver/video/中定義,其中的函式對具體的硬體進行操作,對暫存器進行設定,對顯示緩衝進行對映。主要結構體還有以下幾個。

●structfb_fix_screeninfo:記錄了幀緩衝裝置和指定顯示模式的不可修改資訊。它包含了螢幕緩衝區的實體地址和長度。

●struct fb_var_screeninfo:記錄了幀緩衝裝置和指定顯示模式的可修改資訊。它包括顯示螢幕的解析度、每個畫素的位元數和一些時序變數。

其中變數xres定義了螢幕一行所佔的畫素數,yres定義了螢幕一列所佔的畫素數,bits_per_pixel定義了每個畫素用多少個位來表示。

●struct fb_info:linux為幀緩衝裝置定義的驅動層介面。它不僅包含了底層函式,而且還有記錄裝置狀態的資料。

每個幀緩衝裝置都與乙個fb_info結構相對應。其中成員變數modename為裝置名稱,fontname為顯示字型,fbops為指向底層操作的函式的指標。

lcd驅動開發的主要工作

1編寫初始化函式

初始化函式首先初始化lcd控制器,通過寫暫存器設定顯示模式和顏色數,然後分

配lcd顯示緩衝區。在linux中可以用kmalloc()函式分配一段連續的空間。緩衝區大小為:

點陣行數×點陣列數×用於表示乙個畫素的位元數/8。緩衝區通常分配在大容量的片外sdram中,起始位址儲存在lcd控制暫存器中。本文採用的lcd顯示方式為640×480,16位彩色,則需要分配的顯示緩衝區為640×480×2=600kb。

最後是初始化乙個fb_info結構,填充其中的成員變數,並呼叫register_framebuffer(&fb_info),將fb_info登記入核心。

2編寫成員函式

編寫結構fb_info中函式指標fb_ops對應的成員函式,對於嵌入式系統的簡單實現,只需要下列三個函式就可以了。struct fb_ops

structfb_ops在include/linux/中定義。這些函式都是用來設定/獲取fb_info結構中的成員變數的。當應用程式對裝置檔案進行ioctl操作時候會呼叫它們。

對於fb_get_fix(),應用程式傳入的是fb_fix_screeninfo結構,在函式中對其成員變數賦值,主要是smem_start(緩衝區起始位址)和smem_len(緩衝區長度),最終返回給應用程式。而fb_set_var()函式的傳入引數是fb_var_screeninfo,函式中需要對xres、yres和bits_per_pixel賦值。對於/dev/fb,對顯示裝置的操作主要有以下幾種。

● 讀/寫(read/write)/dev/fb:相當於讀/寫螢幕緩衝區。

● 對映(map)操作:由於linux工作在保護模式,每個應用程式都有自己的虛擬位址空間,在應用程式中是不能直接訪問物理緩衝區位址的。為此,linux在檔案操作file_operations結構中提供了mmap函式,可將檔案的內容對映到使用者空間。

對於幀緩衝裝置,則可通過對映操作,可將螢幕緩衝區的物理位址對映到使用者空間的一段虛擬位址中,之後使用者就可以通過讀寫這段虛擬位址訪問螢幕緩衝區,在螢幕上繪圖了。

●i/o控制:對於幀緩衝裝置,對裝置檔案的ioctl操作可讀取/設定顯示裝置及螢幕的引數,如解析度、顯示顏色數和螢幕大小等。ioctl的操作是由底層的驅動程式

來完成的。在應用程式中,操作/dev/fb的一般步驟如下:開啟/dev/fb裝置檔案;用ioctrl操作取得當前顯示螢幕的引數,如螢幕解析度和每個畫素的位元數,根據螢幕引數可計算螢幕緩衝區的大小;將螢幕緩衝區對映到使用者空間;對映後即可直接讀寫螢幕緩衝區,進行繪圖和**顯示了。

lcd模組化驅動

在對s3c2410的lcd編寫模組化驅動程式時,首先要從核心中去除lcd驅動。這裡需要做一些改動,系統呼叫被加在以下檔案中,需去除:/root/usr/src/arm/linux/kernel/

/root/usr/src/arm/linux/include/arm-arm下的和下的編寫模組化驅動程式,有以下幾個關鍵的函式。

●lcd_kernel_init(void)//當模組被載入時執行

●lcd_kernel_exit(void)//當模組被移出核心空間時被執行

●lcd_kernel1_ioctl(struct*inode,struct*file,unsignedintcmd,unsignedlongarg) //其他功能

每當裝配裝置驅動程式時,系統自動呼叫初始化模組lcd_kernel_init(void)。另乙個必須提供的函式是lcd_kernel_exit(void),它在模組被解除安裝時呼叫,負責進行裝置驅動程式的工作。

執行insmod 命令即可將lcd驅動新增到核心中,執行rmmod lcd命令即可從核心中刪除lcd驅動。

靜態載入lcd驅動

將寫好的lcd驅動程式放到arm/linux/drivers/char目錄下,修改arm/linux/drivers/char/檔案,加上一行:bool'lcd driversupport'config_lcd;修改arm/linux/drivers/char/makefile檔案,加上一行:obj-$(config_lcd)+=

這樣,當再進行makexconfig時,就會選擇是否將lcd驅動編譯進核心。同樣的辦法也可用在其他裝置上。

需要了解嵌入式Linux裝置驅動的工作原理

計算機軟體和整合關鍵詞 linux 嵌入式系統 裝置驅動 核心環境1.1 i o子系統的層次結構1.2 i o驅動軟體的總體目標2.1 檔案系統呼叫介面 cpp view pl2.2基本入口點函式結構 cpp view plaincopystaticssize tglobar read struct...

嵌入式系統的組成

嵌入式系統由硬體和軟體兩大部分組成,硬體一般由高效能微處理器和外圍介面電路組成,軟體一般由作業系統和應用程式構成,軟體和硬體之間由所謂的中間層 bsp層,板級支援包 連線。嵌入式系統的硬體有 嵌入式微處理器 儲存器 輸入輸出 i o a d d a 嵌入式系統的軟體有 作業系統 應用軟體。作業系統是...

嵌入式在電力系統中的應用

宋漢學號 104612310 中南大學資訊科學與工程學院,控制工程,湖南省長沙市,410083 摘要 介紹了基於32位高效能晶元powerpc 8248的嵌入式電力系統閘道器,該閘道器實現了傳統電力系統規約iec 60870 5 103向iec 61850的轉換。主要介紹了系統整體構架 powerp...