• Linux中LCD设备驱动-framebuffer(帧缓冲)【】


    转自:https://blog.csdn.net/linux_devices_driver/article/details/7079442

    1、framebuffer 帧缓冲

        帧缓冲(framebuffer)是Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。

        framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显存的一个映像,将其映射到进程空间后,就可以直接进行读写操作,写操作会直接反映在屏幕上。

        framebuffer是个字符设备,主设备号为29,对应于/dev/fb%d 设备文件。

    通常,使用如下方式(前面的数字表示次设备号)
      0 = /dev/fb0 第一个fb 设备
      1 = /dev/fb1 第二个fb 设备

        fb 也是一种普通的内存设备,可以读写其内容。例如,屏幕抓屏:cp /dev/fb0 myfilefb 虽然可以像内存设备(/dev/mem)一样,对其read,write,seek 以及mmap。但区别在于fb 使用的不是整个内存区,而是显存部分。

    2、fb与应用程序的交互

    对于用户程序而言,它和其他的设备并没有什么区别,用户可以把fb看成是一块内存,既可以向内存中写数据,也可以读数据。fb的显示缓冲区位于内核空间,应用程序可以把此空间映射到自己的用户空间,在进行操作。

    在应用程序中,操作/dev/fbn的一般步骤如下:
    (1)打开/dev/fbn设备文件。
    (2)用ioctl()操作取得当前显示屏幕的参数,如屏幕分辨率、每
    个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。
    (3)用mmap()函数,将屏幕缓冲区映射到用户空间。
    (4)映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示了。

    3、fb的结构及其相关结构体

    在linux中,fb设备驱动的源码主要在Fb.h (linux2.6.28includelinux)和Fbmem.c (linux2.6.28driversvideo)两个文件中,它们是fb设备驱动的中间层,为上层提供系统调用,为底层驱动提供接口。


     

    在fb.h文件中有fb驱动需要使用的很多结构,我们先对这些结构体进行说明:

    (1)、

    一个帧缓冲区对应一个struct fb_info结构,它包括了帧缓冲设备的属性和操作的完整集合,每个帧设备都有一个fb_info结构体。源码如下:

    struct fb_info {
    int node;
    int flags;
    struct mutex lock;/* Lock for open/release/ioctl funcs */互斥锁
    struct fb_var_screeninfo var;/* Current var */当前缓冲区的可变参数
    struct fb_fix_screeninfo fix;/* Current fix */固定参数
    struct fb_monspecs monspecs;/* Current Monitor specs */当前显示器标志
    struct work_struct queue;/* Framebuffer event queue */帧缓冲事件队列
    struct fb_pixmap pixmap;/* Image hardware mapper */图像硬件mapper
    struct fb_pixmap sprite;/* Cursor hardware mapper */光标硬件mapper
    struct fb_cmap cmap;/* Current cmap */当前的调色板
    struct list_head modelist;      /* mode list */
    struct fb_videomode *mode;/* current mode */当前的视频模式


    #ifdef CONFIG_FB_BACKLIGHT如果配置了LCD支持背光灯
    /* assigned backlight device */
    /* set before framebuffer registration, 
      remove after unregister */背光调整
    struct backlight_device *bl_dev;


    /* Backlight level curve */
    struct mutex bl_curve_mutex;
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
    #endif
    #ifdef CONFIG_FB_DEFERRED_IO
    struct delayed_work deferred_work;
    struct fb_deferred_io *fbdefio;
    #endif


    struct fb_ops *fbops;帧缓冲操作函数集
    struct device *device;/* This is the parent */父设备
    struct device *dev;/* This is this fb device */fb设备
    int class_flag;                    /* private sysfs flags */私有的sysfs标志
    #ifdef CONFIG_FB_TILEBLITTING
    struct fb_tile_ops *tileops;    /* Tile Blitting */图块blitting
    #endif
    char __iomem *screen_base;/* Virtual address */虚拟基地址
    unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ ioremap的虚拟内存大小
    void *pseudo_palette;/* Fake palette of 16 colors */ 伪16位调色板
    #define FBINFO_STATE_RUNNING 0
    #define FBINFO_STATE_SUSPENDED 1
    u32 state; /* Hardware state i.e suspend */硬件的状态
    void *fbcon_par;                /* fbcon use-only private area */
    /* From here on everything is device dependent */
    void *par;
    };

    (2)、

    /*
     * Frame buffer operations
     *
     * LOCKING NOTE: those functions must _ALL_ be called with the console
     * semaphore held, this is the only suitable locking mechanism we have
     * in 2.6. Some may be called at interrupt time at this point though.
     */
    fb_ops结构体用来实现对帧缓冲设备的操作,这些函数需要驱动开发人员编写,

    struct fb_ops {
    /* open/release and usage marking */
    struct module *owner;

              打开和释放
    int (*fb_open)(struct fb_info *info, int user);

    int (*fb_release)(struct fb_info *info, int user);

              这两个函数对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要
    /* For framebuffers with strange non linear layouts or that do not
    * work with normal memory mapped access
    */
    ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
      size_t count, loff_t *ppos);
    ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
       size_t count, loff_t *ppos);

               检测可变参数,并调整到支持的值
    /* checks var and eventually tweaks it to something supported,
    * DO NOT MODIFY PAR */
    int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

                设置视频模式
    /* set the video mode according to info->var */
    int (*fb_set_par)(struct fb_info *info);

               设置color寄存器的值
    /* set color register */
    int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
       unsigned blue, unsigned transp, struct fb_info *info);

                批量设置color寄存器,设置颜色表
    /* set color registers in batch */
    int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

              显示空白
    /* blank display */
    int (*fb_blank)(int blank, struct fb_info *info);

              pan显示
    /* pan display */
    int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

              填充矩形
    /* Draws a rectangle */
    void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);

                数据复制
    /* Copy data from area to another */
    void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);

               图形填充
    /* Draws a image to the display */
    void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

               绘制光标
    /* Draws cursor */
    int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

                旋转显示
    /* Rotates the display */
    void (*fb_rotate)(struct fb_info *info, int angle);

                等待blit空闲
    /* wait for blit idle, optional */
    int (*fb_sync)(struct fb_info *info);

                 fb特定的ioctl操作
    /* perform fb specific ioctl (optional) */
    int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
    unsigned long arg);

                  处理32兼容的ioctl操作
    /* Handle 32bit compat ioctl (optional) */
    int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
    unsigned long arg);

                 fb特定的mmap操作
    /* perform fb specific mmap */
    int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

               保存目前的硬件状态
    /* save current hardware state */
    void (*fb_save_state)(struct fb_info *info);

                恢复被保存的硬件状态
    /* restore saved state */
    void (*fb_restore_state)(struct fb_info *info);

               通过fb_info获得framebuffer的能力
    /* get capability given var */
    void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
       struct fb_var_screeninfo *var);
    };

    (3)、

    fb_fix_screeninfo结构体中,记录了用户不能修改的固定显示控制器参数。这些固定的参数如缓冲区的物理地址、缓冲区的长度等等。
    struct fb_fix_screeninfo {
    char id[16]; /* identification string eg "TT Builtin" */

            字符串形式的标识符
    unsigned long smem_start;/* Start of frame buffer mem */

    /* (physical address) */

            fb缓存的开始位置
    __u32 smem_len;/* Length of frame buffer mem */

            fb缓存的长度
    __u32 type; /* see FB_TYPE_* */

            FB_TYPE_*类型
    __u32 type_aux;/* Interleave for interleaved Planes */

             分界
    __u32 visual; /* see FB_VISUAL_* */

           屏幕使用的色彩模式 
    __u16 xpanstep;/* zero if no hardware panning  */

            如果没有硬件panning ,赋0
    __u16 ypanstep;/* zero if no hardware panning  */

    __u16 ywrapstep;/* zero if no hardware ywrap    */

             1行的字节数
    __u32 line_length;/* length of a line in bytes    */

             内存映射I/O的开始位置
    unsigned long mmio_start;/* Start of Memory Mapped I/O   */
    /* (physical address) */

             内存映射I/O的长度
    __u32 mmio_len;/* Length of Memory Mapped I/O  */
    __u32 accel; /* Indicate to driver which */
    /*  specific chip/card we have*/
    __u16 reserved[3];/* Reserved for future compatibility */
    };

    (4)、

    fb_var_screeninfo结构体中存储了用户可以修改的显示器控制参数,例如屏幕分辨率、透明度等等。

    struct fb_var_screeninfo {
    __u32 xres; /* visible resolution */
    __u32 yres;

            可见解析度,即分辨率
    __u32 xres_virtual;/* virtual resolution */
    __u32 yres_virtual;

            虚拟解析度
    __u32 xoffset;/* offset from virtual to visible */
    __u32 yoffset;/* resolution */

            虚拟到可见之间的偏移
    __u32 bits_per_pixel;/* guess what */

            每像素位数,BPP
    __u32 grayscale;/* != 0 Graylevels instead of colors */

            非0时指灰度


    struct fb_bitfield red;/* bitfield in fb mem if true color, */
    struct fb_bitfield green;/* else only length is significant */
    struct fb_bitfield blue;

             fb缓存的RGB位域
    struct fb_bitfield transp;/* transparency */

             透明度

    __u32 nonstd; /* != 0 Non standard pixel format */

            != 0 非标准像素格式

    __u32 activate;/* see FB_ACTIVATE_* */

           
    __u32 height; /* height of picture in mm    */

             屏幕的高度
    __u32 width; /* width of picture in mm     */

             屏幕的宽度
    __u32 accel_flags;/* (OBSOLETE) see fb_info.flags */
             fb_info的标志

    /* Timing: All values in pixclocks, except pixclock (of course) */
    __u32 pixclock;/* pixel clock in ps (pico seconds) */

             /* 像素时钟(皮秒) */
    __u32 left_margin;/* time from sync to picture */

            行切换:从同步到绘图之间的延迟
    __u32 right_margin;/* time from picture to sync */

            行切换:从绘图到同步之间的延迟
    __u32 upper_margin;/* time from sync to picture */

            帧切换:从同步到绘图之间的延迟
    __u32 lower_margin;

             帧切换:从绘图到同步之间的延迟
    __u32 hsync_len;/* length of horizontal sync */

             水平同步的长度
    __u32 vsync_len;/* length of vertical sync */

             垂直同步的长度
    __u32 sync; /* see FB_SYNC_* */
    __u32 vmode; /* see FB_VMODE_* */
    __u32 rotate; /* angle we rotate counter clockwise */

            顺时钟旋转的角度
    __u32 reserved[5];/* Reserved for future compatibility */
    };

    (5)、

    fb_cmap结构体中记录了颜色板信息,即调色板信息。,用户空间可以通过ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令读取或设定颜色表。

    struct fb_cmap {
    __u32 start; /* First entry */第一个元素的入口
    __u32 len; /* Number of entries */元素个数
    __u16 *red; /* Red values */红色、绿色、蓝色
    __u16 *green;  
    __u16 *blue;
    __u16 *transp;/* transparency, can be NULL */透明度
    };

     

    上面这些结构体之间有什么关系呢?看下图:


     

    (6)、

    fb_bitfield 结构体描述每一像素显示缓冲区的组织方式,包含位域偏移、位域长度和MSB 指示,

    struct fb_bitfield {
    __u32 offset; /* beginning of bitfield */

             位域偏移
    __u32 length; /* length of bitfield */

            位域长度
    __u32 msb_right;/* != 0 : Most significant bit is */ 
    /* right */

            MSB
    };

  • 相关阅读:
    Android——活动的基本用法
    开课第五周周总结
    java常用框架
    javaweb学习
    每日日报2021.3.23
    每日日报2021.3.22
    每日日报2021.3.21
    每日日报2021.3.19
    每日日报2021.3.18
    每日日报2021.3.17
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/8670477.html
Copyright © 2020-2023  润新知