免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1743 | 回复: 0
打印 上一主题 下一主题

FrameBuffer驱动学习 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:44 |只看该作者 |倒序浏览

FrameBuffer驱动学习

Daniel Wood 20110301
转载时请注明出处和作者
文章出处:http://danielwood.cublog.cn
作者:Daniel Wood
------------------------------------------------------------
写在前面的话:
这篇文章是自己学习Framebuffer所用,其实里面的东西狠水狠基本的,很多都是从他人的文章中Ctrl+C过来的,如果你没有太多的时间,还是直接跳过了,免得耽误了你的青春,污了你的双眸。

Framebuffer翻译过来是帧缓冲,是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。

帧缓冲设备是标准的字符设备,主设备号为29,对应于/dev/fb/dev/fb1/dev/fb2…)设备文件。

注:代码版本2.6.35.6

帧缓冲数据结构

fb_info结构体

fb.h [include\linux]

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 */
    struct fb_pixmap sprite;    /* Cursor hardware mapper */
    struct fb_cmap cmap;        /* Current cmap */
    struct list_head modelist; /* mode list */
    struct fb_videomode *mode;    /* current mode */

#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;
    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 */
#endif
    char __iomem *screen_base;    /* Virtual address */
    unsigned long screen_size;    /* Amount of ioremapped VRAM or 0 */
    void *pseudo_palette;        /* Fake palette of 16 colors */
#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;
};

fb_infoLinux为帧缓冲设备定义的驱动层接口。它不仅包含了设备的设置参数,状态以及操作函数。每个帧缓冲设备都与一个fb_info结构相对应。

其中node成员域标示了特定的FrameBuffer,实际上也就是一个FrameBuffer设备的次设备号。fb_var_screeninfo结构体成员记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_fix_screeninfo中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址,长度。

fb_ops结构体

fb.h [include\linux]

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);
    /* set color register */
    int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
             unsigned blue, unsigned transp, struct fb_info *info);
    /* 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 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);
    /* perform fb specific ioctl (optional) */
    int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
            unsigned long arg);
    /* Handle 32bit compat ioctl (optional) */
    int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
            unsigned long arg);
    /* perform fb specific mmap */
    int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
    /* 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);
};

它是提供给底层设备驱动的一个接口。通常我们编写字符驱动的时候,要填写一个file_operations结构体,并使用register_chrdev()注册之,以告诉Linux如何操控驱动。当我们编写一个FrameBuffer的时候,就要依照Linux FrameBuffer编程的套路,填写fb_ops结构体。这个fb_ops也就相当于通常的file_operations结构体。

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            */
    __u32 grayscale;        /* != 0 Graylevels instead of colors */
    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 */
};

fb_var_screeninfo结构体成员记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_var_screeninfo中的xres定义屏幕一行有多少个点, yres定义屏幕一列有多少个点, bits_per_pixel定义每个点用多少个字节表示。

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) */
    __u32 smem_len;            /* Length of frame buffer mem */
    __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 */
    unsigned long mmio_start;    /* Start of Memory Mapped I/O */
                    /* (physical address) */
    __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 */
};

fb_fix_screeninfo中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址,长度。当对帧缓冲设备进行映射操作的时候,就是从fb_fix_screeninfo中取得缓冲区物理地址的。上述数据成员都需要在驱动程序中初始化和设置。

其他的结构体都可以在fb.h [include\linux]中找到。

注册与注销帧缓冲设备

定义在fb.h [include\linux]

extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);

实现在fbmem.c [drivers\video]

代码略。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP