嵌入式Linux下驅動STN LCD

admin @ 2014-03-25 , reply:0

    伴隨著高性能嵌入式處理器的飛速發展與普及,特別是ARM處理器系列的出現,嵌入式系統的功能也變得越來越強大。以前的單色LCD已不能滿足現今的各種多媒體應用,彩色LCD被越來越多地應用到嵌入式系統中。同時,在應用需求的促使下,許多工作在Linux下的圖形界面軟體包的開發和移植工作中都涉及到底層LCD驅動的開發問題。

    在硬體採用Intel ASSABET開發板,軟體採用Linux 2.4.19平台,編譯器為arm-linux-gcc的交叉編譯器作為開發的前提下,因為ASSABET開發板上使用的是Sharp 3.9英寸320×240 TFT彩色LCD,現改用Kyocera 7.7英寸640×480 STN型彩色LCD,所以通過對其Linux驅動程序進行改寫和調試,成功地實現了對該種屏的驅動和顯示。

LCD  控制器
    LCD 控制器的功能是顯示驅動信號,進而驅動LCD顯示器。在驅動LCD設計的過程中首要的是配置LCD控制器。在配置LCD控制器中最重要的一步則是幀緩衝區的指定。用戶所要顯示的內容皆是從緩衝區中讀出,從而顯示到屏幕上。幀緩衝區的大小由屏幕的解析度和顯示色彩數決定。驅動幀緩衝的實現是整個驅動開發過程的重點。

    ASSABET開發板採用SA1110作為處理器。SA1110微處理器是Intel公司生產的一種基於 StrongARM環境的微處理器。該處理器內部有一LCD驅動控制器,可支持單、雙屏顯示和最大1024×1024dpi。每個像素數據以4、8、12 或16位編碼后存儲於外部存儲器內,通過LCD的專用DAM控制器,被裝入至532位的FIFO中。在雙屏顯示時,兩個DMA通道分別負責上下屏幕的顯示,但只有第一個DMA通道有調色板緩衝器。幀緩衝器中的已編碼像素數據是作為指針指向256×12位的調色板。調色板的色調數據控制著抖動邏輯,以產生各種灰度和彩色信號並從LCD數據引腳輸出。

顯示屏
    LCD選擇Kyocera公司的7.7英寸STN型LCD。該LCD可在640×480解析度的情況下提供12位彩色顯示。該屏為雙屏掃描模式,具有兩個8位的數據通道,每種基色都由4位的抖動邏輯來產生15級灰度,因此可以顯示最多153=3375種可能的顏色。

驅動LCD的設計
 
    幀緩衝設備
     幀緩衝設備為圖像硬體設備提供了一種抽象化處理。它代表了一些視頻硬體設備,允許應用軟體通過定義明確的界面來訪問圖像硬體設備。這樣軟體無需了解任何涉及硬體底層驅動的東西(如硬體寄存器)。它允許上層應用程序在圖形模式下直接對顯示緩衝區進行讀寫和I/O控制等操作。通過專門的設備節點可對該設備進行訪問,如/dev/fb*。

    Linux下可支持多個幀緩衝設備,最多可達32個,即從/dev/fb0到/dev/fb31。通常情況下,預設的幀緩衝設備為/dev/fb0。

     在SA1110處理器的LCD控制器操作中,幀緩衝器用於存放全部屏幕的所有編碼像素數據。在它的最低位地址處是32或512位元組的緩衝器,用來存放調色板數據表。32位緩衝器用於4、12或16位像素編碼的16項調色板;512位元組緩衝器用於裝入8位像素編碼的256項調色板。在12或16位像素編碼時,不使用調色板,此時的幀緩衝器的起始32位元組必須填入全零。

主要結構體
    struct fb_fix_screeninfo中記錄了幀緩衝設備和指定顯示模式的不可修改信息。它包含了屏幕緩衝區的物理地址和長度。

    struct fb_var_screeninfo中記錄了幀緩衝設備和指定顯示模式的可修改信息。它包括顯示屏幕的解析度、每個像素的比特數和一些時序變數。其中變數 xres定義了屏幕一行所佔的像素數,yres定義了屏幕一列所佔的像素數,bits_per_pixel定義了每個像素用多少個位來表示。

    struct fb_info是Linux為幀緩衝設備定義的驅動層介面。它不僅包含了底層函數,而且還有記錄設備狀態的數據。每個幀緩衝設備都與一fb_info結構相對應。其中成員變數modename為設備名稱,fontname為顯示字體,fbops為指向底層操作的函數的指針。

Linux內核配置與編譯
    使用下面的命令啟動Linux內核配置工具:
    #make menuconfig

    啟動如下內核選項,選擇對應的選項之後,執行下面的命令:
Console drivers --->
Frame-buffer support--->
[*]  Support for frame buffer devices (EXPERIMENTAL)
[*]  SA-1100 LCD support (NEW)
[*]  Advanced low level driver options (NEW)
[*]  16 bpp packed pixels support (NEW)
[*]  Select compiled-in fonts (NEW)
[*]  VGA 88 font
#make dep
#make zImage

驅動幀緩衝的設計
    幀緩衝設備屬於字元設備,採用了“文件層-驅動層”的介面方式。Linux為幀緩衝設備定義的驅動層介面為struct fb_info結構。在文件層次上,Linux為其定義了下面的操作函數:

static struct file_operations fb_fops = { 
   owner: THIS_MODULE, 
   read: fb_read,  /* 讀操作*/ 
   write: fb_write,  /* 寫操作*/ 
   ioctl: fb_ioctl,  /* 控制操作*/ 
   mmap: fb_mmap,  /* 映射操作*/ 
   open: fb_open,  /* 打開操作*/ 
   release: fb_release,  /*關閉操作*/ 
   };

     應用程序層對幀緩衝設備的訪問同對文件的訪問操作類似。在應用程序中,對幀緩衝設備(dev/fb)的操作只需調用文件層的操作函數。首先打開 /dev/fb設備文件;隨後用ioctl操作取得屏幕的解析度和bpp值,從而計算出屏幕緩衝區的大小,並將屏幕的緩衝區映射到用戶空間;最後就可直接對屏幕緩衝區進行圖片顯示。

    嵌入式Linux操作系統對幀緩衝的初始化入口在fbmem.c中的如下定義:

static struct {
 const char *name;
 int (*init)(void);
  int (*setup)(char*);
} fb_drivers[ ]__initdata = {
#ifdef CONFIG_FB_YOURCARD
   { "driver_name", xxxfb_init, xxxfb_setup },
#endif

    通過該入口可進入幀緩衝的初始化函數。下面是對整個幀緩衝的實現過程。

     首先,根據所選擇的STN型LCD先初始化顯示屏幕的解析度(640×480)、每個像素的比特數(實際所選的LCD為12bpp,但在設計中可作為 16bpp來設計。這是因SA1110的LCD控制器對兩者處理方式相同而只有色彩深度的比例不同的緣故)和各種時序值。隨後這些值將會被寫入LCD控制器的控制寄存器LCCR0到LCCR3內,即完成對LCD控制器內一部分寄存器的配置。特殊的一點,因為所選的LCD是12bpp顯示,所以rgbt色彩的深度比值應為4:4:4:0。

    其次對LCD進行顯示緩衝區的分配。該過程由kmalloc函數實現動態分配一片連續的空間,需要分配的緩衝區大小為600K位元組。緩衝區是在SDRAM中分配大容量的地址,存儲器映射至SA1110內,其中上半屏起始地址保存到LCD控制器的寄存器DBAR1中,下半屏起始地址保存到DBAR2中。在此完全初始化一個fb_info結構,填充其中的各成員變數。之後進行中斷處理請求和各種變數和調色板等的設置。然後註冊驅動程序,通過調用register_framebuffer(&fb_info)實現將fb_info登記入內核。最後,啟動GPIO9~2和LCD控制器。

 效果
    因為該設計將驅動作為內核的一部分,而不是模塊載入的方式,所以需重新編譯內核,並將新編譯的Linux內核下載到開發板內。重新啟動系統后,通過應用程序檢測,可以使屏幕顯示任意所需圖片,表明了驅動LCD顯示的設計已成功實現。

     在對嵌入式Linux系統進行驅動LCD的開發時,不僅涉及到對開發板的了解(特別是微處理器和外圍介面),還要求熟練配置Linux內核、掌握 Linux的整個系統啟動過程和Linux下開發設備驅動程序過程,同時開發人員還需掌握所開發的LCD技術資料。本文具體的介紹驅動LCD過程中驅動幀緩衝的設計。該設計的實現使得此LCD可應用在嵌入式開發的多種領域,因此具有實用價值。




[admin via 研發互助社區 ] 嵌入式Linux下驅動STN LCD已經有1021次圍觀

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