lcd驅動解析(二) .

init部分主要完成的任務是:屏的初始化,顯示的初始化,最後打開lcd,背光,等待圖片數據輸入,然後輸出。(產生fbinfo結構體給fbmem.c使用)

用戶操作的流程包括:ioctl控制圖片的顯示屬性(讀取初始化時的配置或者使用bsp操作寄存器改變顯示設置)和顯示圖片的數據源。(概括說就是控制和數據兩條線)

這一節主要分析init部分,就是屬於***fb.c文件的函數。

    驅動程序綁定由內核自動執行,當內核發現一個驅動程序與一個設備匹配時,將調用驅動程序的probe函數,完成對設備的探測及初始化等工作。device與driver是用名字搭配的,其實註冊並部分先後,device註冊時會去找driver,driver註冊的時候會去找device,當配對成功後,driver就從device中獲取必要的數據(使用到資源或者一些參數),然後對設備進行初始化。搭建必要的設備運行環境,比如lcd需要在內存中申請一段空間,用於接收用戶發送過來的數據。只有都準備完畢了,纔可以打開設備,等待用戶操作。(lcd driver還產生了一個結構體fbinfo,存放了用戶可能用到的所有信息,放到fbmem.c中)這樣probe函數的入口參數就可以解釋了

kzalloc

    用kzalloc申請內存的時候, 效果等同於先是用 kmalloc() 申請空間 , 然後用 memset() 來初始化 ,所有申請的元素都被初始化爲 0.

首先爲什麼要使用這個函數,目的是在堆空間分配一段內存給一個指針,然後初始化爲0。其實完成同樣的功能也可以這樣,先定義一個結構體實例,並初始化爲0,然後把這個對象賦值給那個指針。結果都是一個指針指向了一段大小一樣空的內存,只不過一個在堆,一個在棧。不過在堆中更容易控制,可以自己free掉,而不需要等待系統去幫你free。有個不好就是把指針給別人用,別人卻不去free它,那就糟了,這一點還是比不上結構體實例的。

platform_get_resource

 

複製代碼
struct resource *platform_get_resource(struct platform_device *dev,
                                   unsigned int type, unsigned int num)
{
       int i; 
       for (i = 0; i < dev->num_resources; i++) {
//不管你想找哪一類資源,都要從第一個資源看是比對,所以效率嗎貌似有點低,不過一般總資源數也不多。
              struct resource *r = &dev->resource[i]; 
              if (type == resource_type(r) && num-- == 0)
                     return r;
//找到匹配的之後把整個結構體返回。
       }
       return NULL;
//沒找到就返回空。
}
//這裏取出的資源包括中斷號,io端口的寄存器物理地址等。這些資源是設備需要用的,驅動取出後用於靜態申請(就是已知物理地址,中斷號的情況下去申請物理地址和中斷號),可以理解爲,
//告訴系統這段物理地址和中斷號被佔用,不能再分配給其他設備了。如果沒有lcd,這些資源就可以給別人用了。這些都是系統資源啊,大家共用的。
複製代碼
info->mem = request_mem_region(res->start, resource_size(res), pdev->name);
//這就是申請指定的io物理地址空間,告訴系統,這段物理地址被lcd佔用。(後來使用寄存器的物理地址)
info->io = ioremap(res->start, resource_size(res));
//把申請到的物理地址空間映射到虛擬地址空間中,後來操作寄存器都是使用的虛擬地址。

framebuffer_alloc()

framebuffer_alloc()功能是向內核申請一段大小爲sizeof(struct fb_info) + size的空間,其中size的大小代表設備的私有數據空間,並用fb_info的par域指向該私有空間。爲什要價size大小,因爲這樣纔是整個fbinfo的大小,私有數據空間需要與fbinfo一起free,就是說這段數據是不可缺少的,那麼爲什麼不用結構體來存放,這樣與fbinfo就是一個整體了啊,一起free更有說服力。大家注意一下par是個void型的指針,爲什麼要是void型的呢,因爲他自己都不知道他將要指向的私有數據類型,那你用什麼結構體來存放這莫名的私有數據呢。fbinfo這個結構體裏面的成員是定好的,他是與fbmem.c的接口,這個接口結構體中就只有這樣一個私有數據指針是可變的,是給用戶發揮的。這就解釋了爲什麼par是void類型的指針。既然fbinfo是在***fb.c中申請的,作爲數據接口給fbmem.c,那麼在init結束後也是不能釋放的,所以放在堆裏面很安全,在註銷驅動的時候在remove函數內會free掉,很方便是不是?

 關於android lcd doublebuffer問題

DMA從SDRAM FIFO中取數據,送給顯存buffer的時候,中間需要進行處理,比如mix alphableeding,colorkey等工作,這些時間並不長,但是在進行處理時,SDRAM FIFO中的數據無法更新,可以理解爲是基於此FIFO進行合成等工作的,合成完了纔會送到顯存FIFO,送完後等待取出下一張要顯示的圖片,取圖片又是需要時間的,兩個時間加起來就無法忽略了,有明顯的延遲。所以使用doublebuffer,就是行爲原來的兩倍,可以存兩張圖片,一個用來合成,一個用來繪製,兩個交替使用,解決延遲的問題。(這也就是通常說的pan_display)

發佈了0 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章