18_2_帧缓冲

帧缓冲 framebuffer : 是linux系统为显示设备提供的一个接口。

帧缓冲是显示缓冲区的抽象,而不需要考虑底层硬件的差异,允许上层应用在图形模式下,直接对显示缓冲区进行读写操作。

屏幕上的显示点,与显示缓冲区一一对应,可以通过读写显示缓冲区的操作,来控制屏幕上的显示输出。、

帧缓冲设备为标准字符设备,主设备号29,对应于/dev/fb%d设备文件。

1. fb_info 结构体:

是帧缓冲设备最关键的一个数据结构体,简称“FBI”。
FBI中包括了关于帧缓冲设备属性和操作的完整描述,记录了帧缓冲设备的全部信息,包括设备的设置参数、状态以及操作函数指针。每一个帧缓冲设备都必须对应一个FBI。

    struct fb_info {
        int node;
        int flags;
        struct mutex lock;        /* Lock for open/release/ioctl funcs */
        struct mutex mm_lock;        /* Lock for fb_mmap and smem_* fields */
        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 */             //目前的video模式
    #ifdef CONFIG_FB_BACKLIGHT
        /* 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;   //fb_ops, 帧缓冲操作。指向底层操作的函数的指针
        struct device *device;        /* This is the parent */
        struct device *dev;        /* This is this fb device */
        int class_flag; /* private sysfs flags */   //私有标志
    #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 */   //ioremapped的虚拟内存大小。
        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;
        /* we need the PCI or similiar aperture base/size not
         smem_start/size as smem_start may just be an object
         allocated inside the aperture so may not actually overlap */
        struct apertures_struct {
            unsigned int count;
            struct aperture {
                resource_size_t base;
                resource_size_t size;
            } ranges[0];
        } *apertures;
    };
2. fb_ops 结构体:


FBI的成员变量 fbops 为 指向底层操作的行数的指针,这些函数是需要驱动程序开发人员编写的。

    /*
     * 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.
     *
     * The exception to this is the debug related hooks. Putting the fb
     * into a debug state (e.g. flipping to the kernel console) and restoring
     * it must be done in a lock-free manner, so low level drivers should
     * keep track of the initial console (if applicable) and may need to
     * perform direct, unlocked hardware writes in these hooks.
     */
    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);

     
      //根据info->var设置video模式,使用户设置的参数在硬件上有效

        /* 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);    //旋转显示
        /* wait for blit idle, optional */
        int (*fb_sync)(struct fb_info *info);   //等待blit空闲
        /* perform fb specific ioctl (optional) */
        int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
                unsigned long arg);       //fb特定的 ioctl
        /* Handle 32bit compat ioctl (optional) */
        int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
                unsigned long arg);     //32位的compat ioctl
        /* perform fb specific mmap */
        int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);  //fb特定的mmap
        /* get capability given var */
        void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
                 struct fb_var_screeninfo *var);
        /* teardown any resources to do with this framebuffer */
        void (*fb_destroy)(struct fb_info *info);
        /* called at KDB enter and leave time to prepare the console */
        int (*fb_debug_enter)(struct fb_info *info);
        int (*fb_debug_leave)(struct fb_info *info);
    };

3. fb_var_screeninfo 和 fb_fix_screeninfo 结构体

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            */  //定义每个像素点用多少个bit表示
        __u32 grayscale;        /* != 0 Graylevels instead of colors */  //非零时指灰度


      //fb 缓存的 R / G / B 值

        struct fb_bitfield red;        /* bitfield in fb mem if true color, */
        struct fb_bitfield green;    /* else only length is significant */
        struct fb_bitfield blue;
        struct fb_bitfield transp;    /* transparency            */    //透明度
        __u32 nonstd;            /* != 0 Non standard pixel format */ //非标准像素格式
        __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 */
        /* 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 */ //保留
    };

    struct fb_fix_screeninfo {
        char id[16];            /* identification string eg "TT Builtin" */  //字符串形式的标识符
        unsigned long smem_start;    /* Start of frame buffer mem */  //fb缓存的开始位置
                        /* (physical address) */
        __u32 smem_len;            /* Length of frame buffer mem */   //fb缓存的长度
        __u32 type;            /* see FB_TYPE_*        */
        __u32 type_aux;            /* Interleave for interleaved Planes */  //分界
        __u32 visual;            /* see FB_VISUAL_*        */  //记录屏幕使用的色彩模式
        __u16 xpanstep;            /* zero if no hardware panning */
        __u16 ypanstep;            /* zero if no hardware panning */
        __u16 ywrapstep;        /* zero if no hardware ywrap */
        __u32 line_length;        /* length of a line in bytes */  // 1行的字节数
        unsigned long mmio_start;    /* Start of Memory Mapped I/O */  //内存映射I/O的开始位置
                        /* (physical address) */
        __u32 mmio_len;            /* Length of Memory Mapped I/O */  //内存映射I/O的长度
        __u32 accel;            /* Indicate to driver which    */
                        /* specific chip/card we have    */
        __u16 reserved[3];        /* Reserved for future compatibility */  //保留
    };

4. fb_bitfield 结构体:

用来表示 R, G, B 的位域,描述每一个像素显示缓冲区的组织方式,包含位域偏移,位于长度 和 MSB指示。

    /* Interpretation of offset for color fields: All offsets are from the right,
     * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
     * can use the offset as right argument to <<). A pixel afterwards is a bit
     * stream and is written to video memory as that unmodified.
     *
     * For pseudocolor: offset and length should be the same for all color
     * components. Offset specifies the position of the least significant bit
     * of the pallette index in a pixel value. Length indicates the number
     * of available palette entries (i.e. # of entries = 1 << length).
     */
    struct fb_bitfield {
        __u32 offset;            /* beginning of bitfield    */
        __u32 length;            /* length of bitfield        */
        __u32 msb_right;        /* != 0 : Most significant bit is */
                        /* right */
    };

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_fops :

定义于 linux/drivers/video/fbmem.c 文件中。 跟上面的 fb_ops 不同。
帧缓冲设备驱动的文件操作接口函数 统一在 fbmem.c 中实现。一般不需要工程师编写。

    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,
    };

7. 注册和注销帧缓冲设备。

如果注册的帧缓冲设备数超过了 FB_MAX, 则返回 -ENXIO, 注册成功则返回0.

    /**
     *    register_framebuffer - registers a frame buffer device
     *    @fb_info: frame buffer info structure
     *
     *    Registers a frame buffer device @fb_info.
     *
     *    Returns negative errno on error, or zero for success.
     *
     */
    int
    register_framebuffer(struct fb_info *fb_info)
    {
        int i;
        struct fb_event event;
        struct fb_videomode mode;
        if (num_registered_fb == FB_MAX)
            return -ENXIO;
        if (fb_check_foreignness(fb_info))
            return -ENOSYS;
        remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
                         fb_is_primary_device(fb_info));
        num_registered_fb++;
        for (i = 0 ; i < FB_MAX; i++)
            if (!registered_fb[i])
                break;
        fb_info->node = i;
        mutex_init(&fb_info->lock);
        mutex_init(&fb_info->mm_lock);
        fb_info->dev = device_create(fb_class, fb_info->device,
                     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
        if (IS_ERR(fb_info->dev)) {
            /* Not fatal */
            printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
            fb_info->dev = NULL;
        } else
            fb_init_device(fb_info);
        if (fb_info->pixmap.addr == NULL) {
            fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
            if (fb_info->pixmap.addr) {
                fb_info->pixmap.size = FBPIXMAPSIZE;
                fb_info->pixmap.buf_align = 1;
                fb_info->pixmap.scan_align = 1;
                fb_info->pixmap.access_align = 32;
                fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
            }
        }    
        fb_info->pixmap.offset = 0;
        if (!fb_info->pixmap.blit_x)
            fb_info->pixmap.blit_x = ~(u32)0;
        if (!fb_info->pixmap.blit_y)
            fb_info->pixmap.blit_y = ~(u32)0;
        if (!fb_info->modelist.prev || !fb_info->modelist.next)
            INIT_LIST_HEAD(&fb_info->modelist);
        fb_var_to_videomode(&mode, &fb_info->var);
        fb_add_videomode(&mode, &fb_info->modelist);
        registered_fb[i] = fb_info;
        event.info = fb_info;
        if (!lock_fb_info(fb_info))
            return -ENODEV;
        fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
        unlock_fb_info(fb_info);
        return 0;
    }
    /**
     *    unregister_framebuffer - releases a frame buffer device
     *    @fb_info: frame buffer info structure
     *
     *    Unregisters a frame buffer device @fb_info.
     *
     *    Returns negative errno on error, or zero for success.
     *
     * This function will also notify the framebuffer console
     * to release the driver.
     *
     * This is meant to be called within a driver's module_exit()
     * function. If this is called outside module_exit(), ensure
     * that the driver implements fb_open() and fb_release() to
     * check that no processes are using the device.
     */
    int
    unregister_framebuffer(struct fb_info *fb_info)
    {
        struct fb_event event;
        int i, ret = 0;
        i = fb_info->node;
        if (!registered_fb[i]) {
            ret = -EINVAL;
            goto done;
        }
        if (!lock_fb_info(fb_info))
            return -ENODEV;
        event.info = fb_info;
        ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
        unlock_fb_info(fb_info);
        if (ret) {
            ret = -EINVAL;
            goto done;
        }
        if (fb_info->pixmap.addr &&
         (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
            kfree(fb_info->pixmap.addr);
        fb_destroy_modelist(&fb_info->modelist);
        registered_fb[i]=NULL;
        num_registered_fb--;
        fb_cleanup_device(fb_info);
        device_destroy(fb_class, MKDEV(FB_MAJOR, i));
        event.info = fb_info;
        fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
        /* this may free fb info */
        if (fb_info->fbops->fb_destroy)
            fb_info->fbops->fb_destroy(fb_info);
    done:
        return ret;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值