lcd驅動解析(一) .

硬件執行流程1

硬件執行流程2

這兩幅圖的差別在於mix的位置,mix的功能包括alpha blending,color-key,圖層處理等。流程1,這些工作是有軟件完成的,流程2是由硬件完成的。

這個網上找個圖啊,不過lcd驅動基本都是這樣的架構。fbmem.c是已經實現的,×××fb.c是需要我們自己實現的,這關係到具體的lcd屏。

首先,lcd驅動的初始化分爲3個部分,

1 lcd設備的註冊

platform_add_devices(devices, ARRAY_SIZE(devices));

2 lcd系統自帶驅動的註冊(fbmem.c)

register_chrdev(FB_MAJOR,"fb",&fb_fops);

3 lcd自己寫的驅動的註冊(***fb.c)

platform_driver_register(&sep0611fb_driver);

驅動部分爲什麼一分爲二,爲了方便編寫吧,移植等等,驅動開發也只需要編寫下面的一段而已,工作量減小了。那麼其他驅動是否也是這樣安排的呢?

    關於設備部分呢,主要就是關於具體設備的參數,比如說lcd屏,就有一些參數,這些參數根據屏的不同而不同,比如時序參數,使用到GPIO,屏的寬度,屏的分辨率,還有屏控制器寄存器所佔的物理地址,lcd用的中斷等。如果沒有lcd,那麼物理地址空間也不會看到lcd寄存器,lcd寄存器的物理地址也是需要申請的,還會映射爲虛擬地址,便於操作。這些其實都是一個從無到有的過程。爲了驅動lcd屏而存在。在文件系統裏面,設備也是抽象的,它只包含具體設備的信息,驅動要操作具體的設備,就要先獲取相關的信息,找個就是它啊,好比,找到控制這個設備的寄存器,利用寄存器來控制外設。所以註冊的設備信息與設備必須一一對應,才能被驅動所用。這也解釋了驅動爲什麼能驅動硬件的問題。

    fbmem.c中的read,write是給用戶調用的,然後再調用***fb.c中的具體實施環節。自己寫的***fb.c通過register_framebuffer()與系統中的fbmem.c聯繫起來,共同組成驅動部分。

複製代碼
register_framebuffer(struct fb_info *fb_info)
{
.......
fb_info->dev = device_create(fb_class, fb_info->device,
                     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
    //在/dev下面註冊設備,申請次設備號
.......
registered_fb[i] = fb_info;
.......
}
複製代碼

這就把fbmem.c與×××fb.c聯繫起來了。當用戶使用fbmem.c中的open("/dev/fb0"),就會獲得fb的主設備號29,和次設備號0,通過主設備號找到fbmem.c中的read,write等,通過次設備號,可以決定你操作的是那個framebuffer(即那個圖層)。用戶只需要把數據寫入framebuffer,就等於寫入顯存,從硬件流程圖可知,數據從framebuffer到顯存是由DMA硬件完成的,所以在用戶看來,操作framebuffer就是操作顯存,使得圖片可以立即被輸出顯示。(framebuffer是內核空間的一段內存,各個圖層可以共用同一個framebuffer,也可以各自擁有一個獨立的framebuffer)

爲什麼不讓用戶直接操作顯存呢?

顯存本身就是一個設備,也有對應的物理地址,這樣看是可以直接操作的。之所以使用framebuffer,我認識用戶寫的數據,需要處理才能顯示,而如果直接寫入顯存,就直接流入lcd屏了。所以要把用戶數據緩衝下,以便處理(圖層疊加啊,yuv改變爲rgb啊,使用colorkey,alpha-bleeding等),處理完再送入顯存,直接通過hdmi等接口送給lcd屏。

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