幀緩沖設備屬於字符設備,采用了“文件層-驅動層”的接口方式。Linux為幀緩沖設備定義的驅動層接口為struct fb_info結構。在文件層次上,Linux為其定義了下面的操作函數:struct file_operations
軟件運行流程:
在文件層次上,用戶調用struct file_operations的函數操作,在struct file_operations中間接調用struct fb_ops的函數來操作硬件.當向內核注冊FB設備的時候,也注冊了struct fb_ops的指針.當打開fb設備時,先調用fb_drivers[]的xxxfb_init()來初始化設備;
1、開發步驟和框架
涉及的文件:fb.h, fbmem.c, xxxfb.c.
fb.h: 定義了一些結構,變量和宏;
fbmem.c: 主要實現設備入口和初始化,如struct file_operations;
入口點:
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
文件操作:
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,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
get_unmapped_area: get_fb_unmapped_area,
#endif
};
xxxfb.c: 自己添加的設備驅動文件,如struct fb_info;
實現入口點函數: xxxfb_init; xxxfb_setup;
static struct fb_ops xxxfb_ops = {
owner: THIS_MODULE,
fb_open: xxxfb_open, /* only if you need it to do something */
fb_release: xxxfb_release, /* only if you need it to do something */
fb_get_fix: fbgen_get_fix,
fb_get_var: fbgen_get_var,
fb_set_var: fbgen_set_var,
fb_get_cmap: fbgen_get_cmap,
fb_set_cmap: fbgen_set_cmap,
fb_pan_display: fbgen_pan_display,
fb_ioctl: xxxfb_ioctl, /* optional */
};
2、什麼是framebuffer 設備
framebuffer 是一種能夠提取圖形的硬件設備,是用戶進入圖形界面很好的接口。有了framebuffer,用戶的應用程序不需要對底層的驅動的深入了解就能夠做出很好的圖形。
對於用戶而言,它和/dev 下面的其他設備沒有什麼區別,用戶可以把
framebuffer 看成一塊內存,既可以向這塊內存中寫入數據,也可以從這塊內存中讀取數據。
第一個被注冊的framebuffer 的minor 等於0,第二個被注冊的framebuffer的minor 等於1,以此類推。
3、framebuffer 內部結構
數據結構:framebuffer 設備很大程度上依靠了下面四個數據結構。這三個結構在fb.h 中聲明。
Struct fb_var_screeninfo
Struct fb_fix_screeninfo
Struct fb_info
第一個結構是用來描述圖形卡的特性的。通常是被用戶設置的。它包括顯示屏幕的分辨率、每個像素的比 特數和一些時序變量。其中變量xres定義了屏幕一行所占的像素數,yres定義了屏幕一列所占的 像素數,bits_per_pixel定義了每個像素用多少個位來表示。
第二個結構定義了圖形卡的硬件特性,是不能改變的,用戶選定了哪一個圖形卡,那麼它的硬件特性也就 定下來了。它包含了屏幕緩沖區的物理地址和長度。
第三個結構是Linux為幀緩沖設備定義的驅動層接口。它不僅包含了底層函數,而且還有記錄設備狀態的 數據。每個幀緩沖設備都與一fb_info結構相對應。其中成員變量modename為設備名稱, fontname為顯示字體,fbops為指向底層操作的函數的指針。定義了當前圖形卡framebuffer 設 備的獨立狀態,一個圖形卡可能有兩個framebuffer, 在這種情況下,就需要兩個fb_info 結構 。這個結構是唯一在內核空間可見的。
4、設計自己的framebuffer 設備驅動
用戶首先需要添加下面的代碼到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
其次在xxfb.c 中根據自己的需要重新分配顯存大小。例如:
#define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根據自己的硬件設備修改相應的var 信息。主要修改
xxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)函數。
5、如何添加framebuffer 設備驅動
在make menuconfig 的時候首先進入Character devices,選中裡面的Virtualterminal.如果希望控制台在液晶上輸出,則選中Support for console on virtual terminal。(選用了msh(minix shell),再在rc中放入了一條sh < /dev/ttyS0,通過串口輸入的鍵值顯示輸出就能在LCD上顯示了。)
退到上一層界面我們就可以看到Console device 的選項,進入後將光標落在Framebuffer Support 上,按回車鍵進入,在裡面選擇自己所需要的framebuffer設備即可。自己所添加的設備驅動的類型(如果在uclinux 下,應該以*選中,而不是M 選中),在編譯的時候就會產生相應的.o 文件。
在Advanced low level 中可以配置bpp packed pixel support,然後選中Selectcompiled-in fonts即可。
等操作系統運行以後就會在/dev 下面看到fb 這個設備。它的major 應該是29,第一個設備的minor 應該是0。