Linux帧缓冲数据结构和驱动结构总结

来源:互联网 发布:谷歌tts语音数据 编辑:程序博客网 时间:2024/05/01 18:32
fb_info结构体:为便于记忆,简称FBI,FBI中记录了帧缓冲设备的全部信息,每一个帧缓冲设备都必须对应一个FBI。

FBI的部分成员介绍:
fbops:    为fb_ops结构体,是个指向底层操作的函数指针,这些函数是需要驱动人员编写的。
    fb_ops的fb_check_var()函数用于检查可以修改的屏幕参数并调整到合适的值
    fb_ops的fb_set_par()函数使用户设置的屏幕参数在硬件上有效
    fb_ops的fb_fillrect通常使用对应的通用的cfb_fillrect(),定义在drivers/video/cfbfillrect.c文件中
    fb_ops的fb_copyarea通常使用对应的通用的cfb_copyarea(),定义在drivers/video/cfbcopyarea.c文件中
    fb_ops的fb_imageblit通常使用对应的通用的cfb_imageblit(),定义在drivers/video/cfbimgblt.c文件中
    fb_ops的fb_setcolreg函数实现伪颜色表(针对FB_VISUAL_PSEUDOCOLOR、FB_VISUAL_DIRECTCOLOR)和颜色表的填充

var:    为fb_var_screeninfo结构体,记录用户可以修改的显示控制器参数,包括:屏幕分辨率和每个像素点的比特数
    xres定义屏幕一行有多少点
    yres定义屏幕一列有多少点
    bits_per_pixel定义每个点用多少字符表示
    提到的成员都需要在驱动程序中初始化和设置
    该结构体成员red、green、blue均为fb_bitfield结构体类型,分别记录了R、G、B的位域,fb_bitfield结构体描述
    每一像素显示缓冲区的组织方式,包含:位域偏移,位域长度和MSB指示

fix:    为fb_fix_screeninfo结构体,记录用户不能修改的显示控制器参数,如:屏幕缓冲区的物理地址、长度。
    当对帧缓冲设备进行映射操作时,就是从fb_fix_screeninfo中取得缓冲区的物理地址的
    提到的成员都需要在驱动程序中初始化和设置
    该结构体有一名为visual的成员,记录了屏幕使用的色彩模式,在Linux系统中,支持的色彩模式包括以下几种:
    Monochrome(FB_VISUAL_MONO01、FB_VISUAL_MONO10),每个像素是黑或白
    Pseudo color(FB_VISUAL_PSEUDOCOLOR、FB_VISUAL_STATIC_PSEUDOCOLOR),即伪彩色,采用索引颜色显示
    True color(FB_VISUAL_TRUECOLOR),真彩色,分成红、绿、蓝三元色
    Direct color(FB_VISUAL_DIRECTCOLOR),每个像素也是由红、绿、蓝三元色组成,不过,每个颜色值是个索引,需要查表
    Grayscale displays,灰度显示,红、绿、蓝的值都一样。

cmap:    为fb_cmap结构体,记录设备无关的颜色表信息,用户可以通过ioctl()的FBIOGETCMAP和FBIOPUTCMAP命令来读取或设定颜色表


****************************************************************************************************************************************************

文件操作结构体
作为一种字符设备,帧缓冲设备的文件操作结构体定义于/linux/drivers/vedio/fbmem.c中
eg:下面的是摘录的一段代码
static const struct file_operations fb_fops = {
    .owner =    THIS_MODULE,
    .read =        fb_read,
    .write =    fb_write,
    .unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl = fb_compat_ioctl,
#endif
    .mmap =        fb_mmap,
    .open =        fb_open,
    .release =    fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
    .get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
    .fsync =    fb_deferred_io_fsync,
#endif
    .llseek =    default_llseek,
};

帧缓冲设备驱动的文件操作接口函数已经在fbmem.c中被统一实现,一般不需要由驱动工程师再编写。
但分析这些函数对于巩固字符设备驱动知识大有帮助

注:    mmap函数非常关键,它将显示缓冲区映射到用户空间,从而使得用户空间可以直接操作显示缓冲区而省去一次用户空间到内核空间的内存复制过程,提高效率
    ioctl函数最终实现对用户I/O控制命令的执行,eg:
    FBIOGET_VSCREENINFO:获得可变的屏幕参数
    FBIOPUT_VSCREENINFO:设置可变的屏幕参数
    FBIOGET_FSCREENINFO:获得固定的屏幕参数设置
    FBIOPUTCMAP:设置颜色表
    FBIOGETCMAP:获得颜色表

注:    这些函数,别忘了它们的本质,文件操作接口,它们的调用实在用户空间,所以,用户空间操作的话,步骤如下:
    1)打开设备文件(eg:/dev/fbn)
    2)用ioctl()操作取得当前显示屏幕的参数,根据屏幕参数可以计算出屏幕缓冲区的大小
    3)将屏幕缓冲区映射到用户空间
    4)映射后就可以直接读写屏幕缓冲区,进行绘图和图片显示了。

注:    分析完了,之后思考的时候,突然觉得一处没想通,这个文件操作结构体是如何与底层的FBI连接上的呢,其实,就是因为在xxxfb.c里调用了register_framebuffer()函数
    因为这个函数的实现是在fbmem.c里,所以,应该就是在这里了,由于有不同的显示设备,可能会对应不同的文件节点,这个不同应该就可能在这个函数里进行区分吧

*********************************************************************************************************************************************************

注册与注销帧缓冲设备
Linux内核提供了register_framebuffer()和unregister_framebuffer()函数,这两个函数都接受FBI指针为参数,原型为:
int register_framebuffer(struct fb_info* fb_info);
int unregister_framebuffer(struct fb_info* fb_info);

对于register_framebuffer()函数:如果注册的帧缓冲设备数超过了FB_MAX(目前定义为32),则函数返回-ENXIO,注册成功则返回0;

***********************************************************************************************************************************************************

结语:    帧缓冲设备提供给用户空间的file_operations结构体由fbmem.c中的file_operations提供,
    而特定帧缓冲设备fb_info结构体的注册,注销以及其中成员的维护,尤其是fb_ops中成员函数的实现则由对应的xxxfb.c文件实现,
    fb_ops中的成员函数最终会操作LCD控制器硬件寄存器。

***********************************************************************************************************************************************************
***********************************************************************************************************************************************************

帧缓冲设备驱动的模块加载和卸载函数
加载函数中:
    1)申请FBI结构体的内存空间,初始化FBI结构体中固定和可变的屏幕参数,即填充FBI中fix和var成员
    2)更具具体LCD屏幕的特点,完成LCD控制器硬件的初始化
    3)申请帧缓冲设备的显示缓冲区空间
    4)注册帧缓冲设备
卸载函数:相反的工作,即释放FBI结构体内存,关闭LCD,释放显示缓冲区,注销帧缓冲设备

    由于LCD控制器经常被集成在SoC上作为一个独立的硬件模块而存在(成为platform_device),因此,LCD驱动中也经常包含平台驱动。
这样,在帧缓冲设备驱动的模块加载函数中完成的工作只是注册平台驱动,而初始化FBI结构体中的固定和可变参数、LCD控制器硬件的初始化、申请帧缓冲设备的显示缓冲区空间和注册帧缓冲设备的工作则移交到平台驱动的探测函数中完成
    同样的,在使用平台驱动的情况下,释放FBI结构体内存、关闭LCD、释放显示缓冲区以及注销帧缓冲设备的工作也移交到平台驱动的移除函数中完成。

***********************************************************************************************************************************************************

结语:    帧缓冲设备是一种典型的字符设备,它统一了显存,将显示缓冲区直接映射到用户空间。

    帧缓冲设备驱动file_operations中VFS接口函数由fbmem.c文件统一实现。这样,驱动工程师的工作重点将是实现针对特定设备fb_info中的fb_ops的成员函数。

    另外,理解并能灵活的修改fb_info中的var和fix参数非常关键。fb_info中的var参数直接和LCD控制器的硬件设置以及LCD屏幕对应。

    在用户空间,应用程序直接按照预先设置的R、G、B位数和偏移写经过mmap()映射后的显示缓冲区就可实现图形的显示,省去了内存从用户空间到内核空间的复制过程。
***********************************************************************************************************************************************************
***********************************************************************************************************************************************************
0 0
原创粉丝点击