4 linux下的帧缓冲区
Linux操作系统为LCD等显示设备提供了帧缓冲区,它是一种驱动程序接口【3】。帧缓冲区为图像硬件设备提供了一种抽象化处理,那么应用软件无需关心硬件设备的细节,就可以通过定义明确的界面来访问图像硬件设备。所以为LCD硬件设备编写驱动程序,实际上就是为帧缓冲区编写驱动程序, 它们的关系如下图1-1所示。
把硬件设备抽象化为帧缓冲区设备,首先要指定LCD的帧缓冲区,在fb.h文件中,其结构体fb_info为帧缓冲设备定义了驱动层接口,它不仅包含了底层函数,而且还可以记录设备状态的数据。每个帧缓冲设备都与一个fb_info结构相对应。其中成员变量modename为设备名称,fontname为显示字体,node为指向底层操作的函数的指针:
struct fb_info {
char modename[40];
kdev_t node; int open;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_cmap cmap;
struct fb_ops *fbops; …};
1)Struct fb_fix_screeninfo:定义了显示输出设备自身的属性,如屏幕缓冲区的物理地址和长度。
2)Struct fb_var_screeninfo:记录了帧缓冲设备和指定显示模式的可修改信息。它包括显示屏幕的分辨率、每个像素的比特数和一些时序变量。其中变量xres定义了屏幕一行所占的像素数,yres定义了屏幕一列所占的像素数,bits_per_pixel定义了每个像素用多少个位来表示。
帧缓冲设备也属于字符设备(文件设备的一种,还有块设备),要实现“文件层-驱动层”的接口方式来对LCD进行驱动就必须定义一个类似于File_operationes可实现文件设备操作数据结构fb_ops,然后编写子函数对fb_ops的各个域进行填充:
struct fb_ops {
struct module *owner;
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con, struct fb_info *info);
int (*fb_get_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
int (*fb_set_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma); …};
这个结构中的每一个字段都必须指向驱动程序中实现特定操作的函数,对于不支持的操作,对应的字段可以被置为NULL,或留到后续开发时载添加。
5 帧缓冲区驱动程序的编写
为LCD显示设备指定了帧缓冲区后,要实现LCD驱动实际上就是编写帧缓冲区的驱动程序。在编写帧缓冲区的驱动程序时,首先要对指出与fb_info中fb_ops结构相对应的成员函数,然后分别实现它们,再对LCD的显示进行初始化。只有实现了这些成员子函数才能在“文件层-驱动层”实现系统调用【4】,从而使应用程序可直接操作显示硬件。现分述如下:
5.1 编写结构体fb_info中fb_ops及其对应的成员函数
本系统中定义了特定操作所对应的成员函数,代码如下:
static struct fb_ops s1d13xxxfb_ops = {
owner: THIS_MODULE,
fb_get_fix: s1d13xxxfb _get_fix,
fb_get_var: s1d13xxxfb _get_var,
fb_set_var: s1d13xxxfb _set_var,
fb_get_cmap: s1d13xxxfb _get_cmap,
fb_set_cmap: s1d13xxxfb _set_cmap,
fb_mmap: s1d13xxx_mmap, …};