深圳技師學院 梁 志 郭惠婷 吳躍前
現(xiàn)代大部分智能設備所用操作系統(tǒng)是linux,其中顯示圖像是不可缺少的功能。本文分析圖像顯示所用的linux Frambuffer的工作原理、底層設備驅(qū)動注冊和應用層的使用。
Linux Frambuffer 中文名簡稱為linux幀緩沖區(qū),可以理解其為linux系統(tǒng)對底層圖像設備進行抽象而形成的抽象層(中間層),它屏蔽了圖像硬件的底層差異,向用戶態(tài)進程提供了一個接口方便應用層程序顯示圖像。
在不帶操作系統(tǒng)的情況下,要液晶屏顯示圖像,首先得驅(qū)動液晶屏,這需要根據(jù)具體型號液晶屏的分辨率、時延參數(shù)、位色等相關硬件參數(shù)去配置相關的硬件寄存器,而所用編程語言一般是嵌入式C語言,明顯這樣顯示圖像的操作對于應用工程師有非常大難度和操作上的麻煩。
在帶操作系統(tǒng)的況下,需要液晶屏顯示圖像,應用工程師只需知道底層的圖像設備已經(jīng)給內(nèi)核抽象成一個緩存區(qū)(這個緩存區(qū)就可以理解為Frambuffer),這個緩存區(qū)一般每一個INT型數(shù)據(jù)就對應著屏上的一個像素點顯示數(shù)據(jù).應用工程師只需要把圖像數(shù)據(jù)寫到緩存沖區(qū),緩存沖區(qū)的數(shù)據(jù)會由底層驅(qū)動傳輸?shù)揭壕辽?。由此可見應用程序工程師顯示圖像再不需要關注圖像硬件操作,把更多精力放在應用邏輯上的思考。
Linux Frambuあer在系統(tǒng)中位置示意圖如圖1所示:
圖1
由圖1可見從應用到硬件,共分三層。Linux Framebuあer 處于系統(tǒng)中間位置,是linux 內(nèi)核顯示子系統(tǒng),對下層提供了相應的注冊接口,讓下層的圖像硬件設備注冊進內(nèi)核;對上層的應用程序提供系統(tǒng)調(diào)用,讓應用程序簡單操作顯示圖像。
(1)Linux 內(nèi)核顯示子系統(tǒng)層:
在Linux內(nèi)核中顯示子系統(tǒng)定義了很多信息.其中重要的結(jié)構(gòu)體信息有:
fb_info :用于定義幀緩存設備的相關信息,比如:可變參數(shù),固定參數(shù),底層操作函數(shù)指針。
fb_var_screeninfo:描述幀緩存設備可以修改的參數(shù),如:長寬等
fb_ fi x_screeninfo:描述幀緩存設備固定的參數(shù),比如:緩存首地址,緩存長度等
fb_ops:描述幀緩存設備具體硬件操作的函數(shù)指針,是底層硬件操作的抽象,比如fb_open、fb_release、fb_read、fb_write、fb_ioctl、fb_mmap等:
重要的函數(shù)如下:
register_framebuffer():底層硬件驅(qū)動注冊函數(shù),底層驅(qū)動通過設置fb_info后調(diào)用該函數(shù)向系統(tǒng)注冊。
unregister_framebuffer():底層硬件驅(qū)動注鎖函數(shù),底層驅(qū)動通過該函數(shù)向系統(tǒng)注銷自身。
(2)底層硬件設備驅(qū)動層:
Linux framebuffer是一個字符設備(主設備號是29),在內(nèi)核中使用platform驅(qū)動模型實現(xiàn),platform device描述了設備相關的硬件信息,主要通過結(jié)構(gòu)體resource描述幀緩存設備所用的地址資源,中斷資源等等。
platform driver描述設備相關軟件信息,主要實現(xiàn)幀緩存設備具體的寄存器相關操作。
比如幀設備(LCD)platform driver實現(xiàn)過程實如下:
(1)通過platform_get_resource從platform device獲得設備所用資源。
(2)通過kzalloc申請顯存空間大小。
(3)初始化設備控件器所使用的GPIO,主要初始化引腳功能選擇、引腳驅(qū)動能力。
(4)設備驅(qū)動信號初始化,其中重點設置行同步信號,像素時鐘信號,幀同步信號,數(shù)據(jù)使能號,其設置要根據(jù)硬件手冊和控制器手冊來配置。
(5)定義一個fb_info并始化相關成員,指定設備可變和固定參數(shù)。
(6)調(diào)用register_framebuあer()把設備注冊進內(nèi)核。
(7)最實現(xiàn)一個注銷設備操作,這時使用unregister_framebuffer。
在應用層使用framebuffer顯示圖像前,需要了解映射,如圖2所示:
因硬件顯示設備的物理顯示區(qū)是通過幀緩存區(qū)操作,而幀緩存區(qū)是處于內(nèi)核空間,應用程序不能隨意操作,此時可以通過系統(tǒng)調(diào)用mmap把幀緩存映射到用戶空間,在用戶空間中創(chuàng)建出幀緩存映射區(qū)(用戶圖像數(shù)據(jù)緩存區(qū)),以后只需把用戶圖像數(shù)據(jù)寫入到幀緩存映射區(qū)就可在硬件設備上顯示圖像。
具體實現(xiàn)流程如下:
(1)打開幀設備的設備文件,常用設備文件為/dev/f0。
(2)通過系統(tǒng)調(diào)用ioctl函數(shù)獲得幀設備相關信息,比如幀設備的寬、高和像素位等。
(3)通過mmap映射內(nèi)核幀緩存區(qū)到用戶空間圖像數(shù)據(jù)緩存區(qū),映射區(qū)的大小由幀設備的寬高等參數(shù)確定。
(4)把圖像數(shù)據(jù)復制到用戶空間圖像數(shù)據(jù)緩存區(qū),圖像就可以在幀設備上顯示出來。
(5)使用完后 ,調(diào)用close關閉設備。
Linux frambuffer 的出現(xiàn)大大簡化對顯示設備的操作,不過需要注意的是framebuffer最大支持32顯示緩存。