怎樣寫 Linux LCD 驅動程式

來源:互聯網
上載者:User

 

怎樣寫 Linux LCD 驅動程式(轉) 作者:
劉鵬 日期:

2008-12-27

本文分析了frame buffer 裝置驅動的主要資料結構,在此基礎上介紹了LCD驅動程式的開發。 基本原理
  • 通過 framebuffer ,應用程式用 mmap 把顯存映射到應用程式虛擬位址空間,將要顯示的資料寫入這個記憶體空間就可以在螢幕上顯示出來;
  • 驅動程式分配系統記憶體作為顯存;實現 file_operations 結構中的介面,為應用程式服務;實現 fb_ops 結構中的介面,控制和操作 LDC 控制器;
  • 驅動程式將顯存的起始地址和長度傳給 LCD 控制器的寄存器 (一般由 fb_set_var 完成) , LDC 控制器會自動的將顯存中的資料顯示在 LCD 屏上。
寫 framebuffer 驅動程式要做什麼
  • 簡單的講,framebuffer 驅動的功能就是分配一塊記憶體作顯存,然後對 LCD 控制器的寄存器作一些設定。
  • 具體來說:
    1. 填充一個 fbinfo 結構
    2. 用 reigster_framebuffer (fbinfo*) 將 fbinfo 結構註冊到核心
  • 對於 fbinfo 結構,最主要的是它的 fs_ops 成員,需要針對具體裝置實現 fs_ops 中的介面
  • 考慮是否使用中斷處理
  • 考慮記憶體訪問方式
    1. 顯卡不內建顯存的,分配系統記憶體作為顯存
    2. 顯卡內建顯存的,用 I/O 記憶體介面進行訪問 (request_mem_region / ioremap),
  • 關於如何寫驅動的參考資料,在網站 http: /linux-fbdev.sourceforge.net/HOWTO/index.html 可以找到 "Linux Frame buffer Driver Writing HOWTO"
LCD 模組 / 驅動程式 / 控制器

關於LCD 裝置資料可參考如下資料:

  • Datasheet of LCD device
  • 書:液晶顯示技術
  • 書:液晶顯示器件
什麼是 frame buffer 裝置

frame buffer 裝置是圖形硬體的抽象,它代表了圖形硬體的偵緩衝區,允許應
用程式通過指定的介面訪問圖形硬體。因此,應用程式不必關心底層硬體細節。

裝置通過特定的裝置節點訪問,通常在 /dev 目錄下,如 /dev/fb*。

更多關於 frame buffer device 的資料可以在以下兩個檔案中找到: linux
/Documentation/fb/framebuffer.txt 和 linux /Documentation/fb
/interal.txt,但這些資料內容不多,還需要看看結合代碼具體分析。

Linux Frame Buffer 驅動程式階層

Frame Buffer 裝置驅動可以從三個層次來看:

  1. 應用程式與系統調用;
  2. 適用於所有裝置的通用代碼,避免重複,包括 file_operations 結構、register/unregister framebuffer 介面等;
  3. 操作具體硬體的代碼,主要是 fs_ops 結構。

在 Linux 核心中,Frame Buffer 裝置驅動的源碼主要在以下兩個檔案中,它們
處於 frame buffer 驅動體繫結構的中介層,它為上層的使用者程式提供系統調用,
也為底層特定硬體驅動提供了介面:

  1. linux/inlcude/fb.h
  2. linux/drivers/video/fbmem.c
資料結構

標頭檔 fb.h 定義了所有的資料結構:

  • fb_var_screeninfo:描述了一種顯卡顯示模式的所有資訊,如寬、高、色彩深度等,不同的顯示模式對應不同的資訊;
  • fb_fix_screeninfo:定義了顯卡資訊,如 framebuffer 記憶體的起始地址,地址長度等;
  • fb_cmap:裝置獨立的 colormap 資訊,可以通過 ioctl 的 FBIOGETCMAP 和 FBIOPUTCMAP 命令設定 colormap;
  • fb_info:包含當前 video card 的狀態資訊,只有 fb_info 對核心可見;
  • fb_ops : 應用程式使用 ioctl 系統叫用作業底層的 LCD 硬體,fb_ops 結構中定義的方法用於支援這些操作;
  • 這些結構相互之間的關係如下所示:
framebuffer 驅動主要資料結構
介面

fbmem.c 實現了所有驅動使用的通用代碼,避免了重複。

全域變數:

     struct fb_info *registered_fb [FB_MAX]
int num_registered_fb;

這個兩個變數用於記錄正在使用的 fb_info 結構執行個體。fb_info 代表 video card 的目前狀態,所有的 fb_info
結構都放在數組中。當一個 frame buffer 在核心中登記時,一個新的 fb_info
結構被加入該數組,num_registered_fb 加 1。

fb_drivers 數組:

static struct {
const char *name;
int (*init)(void);
int (*setup)(void);
} fb_drivers[] __initdata= { ....};

若 frame buffer 驅動程式是靜態連結到核心中,一個新的 entry 必須要加到這個表中。 若該驅動程式是使用 insmod/rmmod 動態載入到核心,則不必關心這個結構。

static struct file_operations fb_ops ={
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release
};

這是使用者應用程式的介面,fbmem.c 實現了這些函數。

register/unregister framebuffer:

 register_framebuffer(struct fb_info *fb_info)
unregister_framebuffer(struct fb_info *fb_info)

這是底層 frame buffer 裝置驅動程式的介面。驅動程式使用這對函數實現註冊和撤銷操作。底層驅動程式的工作基本上是填充 fb_info 結構,然後註冊它。

一個 LCD controller 驅動程式

實現一個 LCD controller 驅動程式主要做如下兩步:

  • 分配系統記憶體作顯存
  • 根據具體的硬體特性,實現 fb_ops 的介面
  • 在 linux/drivers/fb/skeletonfb.c 中有一個 frame buffer 驅動程式的架構,它樣本了怎樣用很少的代碼實現一個 frame buffer 驅動程式。
分配系統記憶體作為顯存

由於大多數 LDC controller 沒有自己的顯存,需要分配一塊系統記憶體作為顯存。
這塊系統記憶體的起始地址和長度之後會被存放在 fb_fix_screeninfo 的
smem_start 和 smem_len 域中。該記憶體應該是物理上連續的。

對於帶獨立顯存的顯卡,使用 request_mem_region 和 ioremap 將顯卡外設記憶體映射到處理器虛擬位址空間。

實現 fb_ops 結構

目前還沒有討論的 file_operations 方法是 ioctl ()。使用者應用程式使用
ioctrl 系統叫用作業 LCD 硬體。fb_ops 結構中定義的方法為這些操作提供支
持。注意, fb_ops 結構不是 file_operations 結構。fb_ops 是底層操作的抽
象,而 file_operations 為上層系統調用介面提供支援。

下面考慮需要實現哪些方法。ioctl 命令和 fb_ops 結構中的介面之間的關係如
下所示:

    FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display

只要我們實現了那些 fb_XXX 函數,那麼使用者應用程式就可以使用 FBIOXXXX 宏
來操作 LDC 硬體了。那怎麼實現那些介面呢?可以參考下
linux/drivers/video 目錄下的驅動程式。

在眾多介面中, fb_set_var 是最重要的。它用於設定 video mode 等資訊。下
面是實現 fb_set_var 函數的通用步驟:

  1. 檢查是否有必要設定 mode
  2. 設定 mode
  3. 設定 colormap
  4. 根據上面的設定重新設定 LCD controller 寄存器

其中第四步是底層硬體操作。

Reference
  • Writing Linux LCD drivers―深入分析framebuffer裝置驅動的結構
  • Linux Frame Buffer Driver HOWTO
  • s3c2410_lcd frame buffer 驅動分析
  • Linux 2.6 Device Model
  • Linux 2.6 核心裝置模型
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.