Linux监控系统开发详解(四)--- framebuffer驱动分析

来源:互联网 发布:java中的方法是什么 编辑:程序博客网 时间:2024/05/13 13:24

 Framebuffer驱动


 为什么要用frambuffer

 如果我们的系统要用GUI(图形界面接口),比如minigui,MicroWindows.这时LCD设备驱动程序就应该编写成frambuffer接口,而不是编写成仅仅操作底层的LCD控制器接口。


 什么是frambuffer设备
        frambuffer设备层是对图像设备的一种抽象,它代表了视频硬件的帧缓存,使得应用程序通过定义好的接口就可以访问硬件。所以应用程序不需要考虑底层的(寄存器级)的操作。应用程序对设备文件的访问一般在/dev 目录,如 /dev/fb*.Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进行操作。用户可以将 Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象 的,统一的,用户不必关心物理显存的位置、换页机制等等具体细节,这些都是由Framebuffer设备驱动来完成的,但Framebuffer本身不具备任何运算数据的能力,就只好比是一个暂时存放水的水池,CPU将运算后的结果放到这个水池,水池再将结果流到显示器,中间不会对数据做处理,应用程序也可以直接读写这个水池的内容。在嵌入式系统中一般没有专门的显存,而仅仅是从RAM(SDRAM)空间中分配一段显示缓冲区,典型结构如下图所示:



一块LCD屏不但需要LCD驱动器,还需要有相应的LCD控制器。通常LCD驱动器会以COF/COG的形式与LCD玻璃基板制作在一起,而LCD控制器则由外部电路来实现。许多MCU内部直接集成了LCD控制器,通过LCD控制器可以方便地控制STN和TFT屏。
3.6.3 linux frambuffer 驱动源码分析
        linux中frambuffer接口的所有功能实现都包括在下面两个文件中:
       1) linux/include/linux/fb.h 
       2)linux/drivers/video/fbmem.c 
       下面详细分析这两个文件: 


3.6.3.1 fb.h 

所有frambuffer重要的结构体都定义在这个文件中。下面逐个分析他们:
        1) fb_var_screeninfo 
       这个结构用来描述一个显卡可以被设置的特性,在fb_var_screeninfo结构体里有我们设备需要的,比如分辨率等信息。 

struct fb_var_screeninfo {  

    __u32 xres;         /* 视口水平分辨率      */  

    __u32 yres;  

    __u32 xres_virtual;     /* 虚拟屏幕水平分辨率        */  

    __u32 yres_virtual;  

    __u32 xoffset;          /* 偏移视口与虚拟屏幕水平分辨率偏移 */  

    __u32 yoffset;            

  

    __u32 bits_per_pixel;       /* 像素的位数            */  

    __u32 grayscale;        /* 灰度标志,如果为1代表是灰度 */  

  

    struct fb_bitfield red;     /* 如果是真彩色,这个是颜色位,如果不是那么只                                 有结构的大小重要,其他表示的信息无关紧要 */  

    struct fb_bitfield green;     

    struct fb_bitfield blue;  

    struct fb_bitfield transp;  /* 透明度      */    

  

    __u32 nonstd;           /* 非标准颜色表示标志位 */  

    __u32 activate;         /* 参照 FB_ACTIVATE_*     */  

    __u32 height;           /* 在内存地址空间的长度    */  

    __u32 width;            /* 在内存地址空间的宽度     */  

  

    __u32 accel_flags;      /* (不用了) 参照 fb_info.flags */  

  

    /* 时序: 以下所有的值单位都是pixclock, 当然除了pixclock */  

    __u32 pixclock;         /* 每秒像素值 */  

    __u32 left_margin;      /* 从sync信号到显示真正的像素的时钟个数 */  

    __u32 right_margin;     /* 从真正显示像素到sync信号的时钟个数  */  

    __u32 upper_margin;     /* 上面两个是针对列像素的,这个针对行的   */  

    __u32 lower_margin;  

    __u32 hsync_len;        /* 水平sync信号的长度  */  

    __u32 vsync_len;        /* 垂直sync信号的长度  */  

    __u32 sync;         /* 参照 FB_SYNC_*     */  

    __u32 vmode;            /* 参照 FB_VMODE_*        */  

    __u32 rotate;           /* angle we rotate counter clockwise */ 译者注:这个不知道具体是什么  

    __u32 reserved[5];      /* 保留 */  

};  

2) fb_fix_screeninfon 
        这个结构体定义了一些显示设备的特性,这些特性当设备的工作模式确定之后就不能改变了。例如:frambuffer 内存的起始地址。这个地址是根据模式的不同而不同。一旦你用了某种模式,你就不要在想去改变他的起始地址了。在这种情况下,你可以获得显示设备的内存 区域地址,但是你不能更改他。

struct fb_fix_screeninfo {  

    char id[16];            /* 身份表示符,例如 "TT Builtin" */  

    unsigned long smem_start;   /* frame buffer内存的开始地址 */  

                    /* (物理地址) */  

    __u32 smem_len;         /* frame buffer内存地址的长度 */  

    __u32 type;         /* 参照 FB_TYPE_*     */  

    __u32 type_aux;         /* Interleave for interleaved Planes */  

    __u32 visual;           /* 参照 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;      /* 每行的长度,单位字    */  

1.         unsigned long mmio_start;   /* I/O 内存的开始地址   */  

2.                         /* (物理地址) */  

3.         __u32 mmio_len;         /* I/O内存的长度  */  

4.         __u32 accel;            /* 对驱动程序的标示:是哪个设备*/  

5.         __u16 reserved[3];      /* 保留 */  

6.     };  

3) fb_cmap 
        调色板信息,这个结构是设备依赖的。应用程序可以通过ioctls的FBIOGETCMAP和FBIOPUTCMAP命令来获得和设置这个结构。

      struct fb_cmap {   

1.         __u32 start; /* First entry */   

2.         __u32 len; /* Number of entries */   

3.         __u16 *red; /* Red values */   

4.         __u16 *green;   

5.         __u16 *blue;   

6.         __u16 *transp; /* transparency can be NULL */   

7.     };  

4)fb_info 
        这个结构代表了一个显示设备的当前状态。他仅对内核可见。除了fb_info结构,内核还有一个fb_ops结构,定义了一些驱动必须的操作函数。

1.     struct fb_info {  

2.         int node;  

3.         int flags;  

4.         struct mutex lock;      /* Lock for open/release/ioctl funcs */  

5.         struct mutex mm_lock;       /* Lock for fb_mmap and smem_* fields */  

6.         struct fb_var_screeninfo var;   /* Current var */  

7.         struct fb_fix_screeninfo fix;   /* Current fix */  

8.         struct fb_monspecs monspecs;    /* Current Monitor specs */  

9.         struct work_struct queue;   /* Framebuffer event queue */  

10.     struct fb_pixmap pixmap;    /* Image hardware mapper */  

11.     struct fb_pixmap sprite;    /* Cursor hardware mapper */  

12.     struct fb_cmap cmap;        /* Current cmap */  

13.     struct list_head modelist;      /* mode list */  

14.     struct fb_videomode *mode;  /* current mode */  

15.   

16. #ifdef CONFIG_FB_BACKLIGHT   

17.     /* assigned backlight device */  

18.     /* set before framebuffer registration  

19.        remove after unregister */  

20.     struct backlight_device *bl_dev;  

21.   

22.     /* Backlight level curve */  

23.     struct mutex bl_curve_mutex;      

24.     u8 bl_curve[FB_BACKLIGHT_LEVELS];  

25. #endif   

26. #ifdef CONFIG_FB_DEFERRED_IO   

27.     struct delayed_work deferred_work;  

28.     struct fb_deferred_io *fbdefio;  

29. #endif   

30.   

31.     struct fb_ops *fbops;  

32.     struct device *device;      /* This is the parent */  

33.     struct device *dev;     /* This is this fb device */  

34.     int class_flag;                    /* private sysfs flags */  

35. #ifdef CONFIG_FB_TILEBLITTING   

36.     struct fb_tile_ops *tileops;    /* Tile Blitting */  

37. #endif   

38.     char __iomem *screen_base;  /* Virtual address */  

39.     unsigned long screen_size;  /* Amount of ioremapped VRAM or 0 */   

40.     void *pseudo_palette;       /* Fake palette of 16 colors */   

41. #define FBINFO_STATE_RUNNING    0  

42. #define FBINFO_STATE_SUSPENDED  1   

43.     u32 state;          /* Hardware state i.e suspend */  

44.     void *fbcon_par;                /* fbcon use-only private area */  

45.     /* From here on everything is device dependent */  

46.     void *par;  

47.     /* we need the PCI or similiar aperture base/size not 

48.        smem_start/size as smem_start may just be an object 

49.        allocated inside the aperture so may not actually overlap */  

50.     resource_size_t aperture_base;  

51.     resource_size_t aperture_size;  

52. };  

5)struct fb_ops
       应用程序可以通过ioctl()系统调用来操作LCD硬件这些操作需要fb_ops中的函数的支持。 

    /*

*Frame buffer operations

*

*LOCKING NOTE: those functions must _ALL_ be called with the

console

*semaphore held, this is the only suitablelocking 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 writesin these hooks.

*/

1.     struct fb_ops {  

2.         /* open/release and usage marking */  

3.         struct module *owner;  

4.         int (*fb_open)(struct fb_info *info, int user);  

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

6.       

7.         /* For framebuffers with strange non linear layouts or that do not 

8.          * work with normal memory mapped access 

9.          */  

10.     ssize_t (*fb_read)(struct fb_info *info, char __user *buf,  

11.                size_t count, loff_t *ppos);  

12.     ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,  

13.                 size_t count, loff_t *ppos);  

14.   

15.     /* checks var and eventually tweaks it to something supported 

16.      * DO NOT MODIFY PAR */  

17.     int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);  

18.   

19.     /* set the video mode according to info->var */  

20.     int (*fb_set_par)(struct fb_info *info);  

21.   

22.     /* set color register */  

23.     int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,  

24.                 unsigned blue, unsigned transp, struct fb_info *info);  

25.   

26.     /* set color registers in batch */  

27.     int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);  

28.   

29.     /* blank display */  

30.     int (*fb_blank)(int blank, struct fb_info *info);  

31.   

32.     /* pan display */  

33.     int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);  

34.   

35.     /* Draws a rectangle */  

36.     void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);  

37.     /* Copy data from area to another */  

38.     void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);  

39.     /* Draws a image to the display */  

40.     void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);  

41.   

42.     /* Draws cursor */  

43.     int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);  

44.   

45.     /* Rotates the display */  

46.     void (*fb_rotate)(struct fb_info *info, int angle);  

47.   

48.     /* wait for blit idle optional */  

49.     int (*fb_sync)(struct fb_info *info);  

50.   

51.     /* perform fb specific ioctl (optional) */  

52.     int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,  

53.             unsigned long arg);  

54.   

55.     /* Handle 32bit compat ioctl (optional) */  

56.     int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,  

57.             unsigned long arg);  

58.   

59.     /* perform fb specific mmap */  

60.     int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);  

61.   

62.     /* get capability given var */  

63.     void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,  

64.                 struct fb_var_screeninfo *var);  

65.   

66.     /* teardown any resources to do with this framebuffer */  

67.     void (*fb_destroy)(struct fb_info *info);  

68. };  

6)主要结构关系

1.     struct fb_info   

2.       | | fb_var_screeninfo   

3.       | | fb_fix_screeninfo   

4.       | | fb_cmap   

5.       | | modename[40]   

6.     struct fb_ops ---|--->ops on var   

7.       | | fb_open   

8.       | | fb_release   

9.       | | fb_ioctl   

10.   | | fb_mmap   

11. struct fbgen_hwswitch -|-> detect   

12.   | | encode_fix   

13.   | | encode_var   

14.   | | decode_fix   

15.   | | decode_var   

16.   | | get_var   

17.   | | set_var   

18.   | | getcolreg   

19.   | | setcolreg   

20.   | | pan_display   



3.6.3.2fbmem.c 
       fbmem.c 是frambuffer驱动的核心,他向上给应用程序提供了系统调用接口,向下对特定的硬件提供底层的驱动接口。底层驱动可以通过接口向内核注册自己。fbmem.c提供了frambuffer驱动的所有接口代码,从而避免重复的工作。
        1) 全局变量

1.     struct fb_info*registered_fb[FB_MAX];

2.     int num_registered_fb;

这两个变量用来标识系统中正在使用的fb_info结构,fb_info代表了显示设备当前的状态。所有的fb_info结构体都保存在全局数组中。当一个 新的frambuffer注册到内核,一个新的项就会加入到这个数组中并且 num_registered_fb加一。

1.     static struct {   

2.         const char *name;   

3.         int (*init)(void);   

4.         int (*setup)(void);   

5.     } fb_drivers[] __initdata= { ....};   

如果一个frambuffer 驱动模块是静态链接到内核的,那么必须在这个结构中加入新项,如果用动态加载模块的方法,就不用考虑这个结构了。

1.     static struct file_operations fb_ops ={   

2.         owner: THIS_MODULE,   

3.         read: fb_read,   

4.         write: fb_write,   

5.         ioctl: fb_ioctl,   

6.         mmap: fb_mmap,   

7.         open: fb_open,   

8.         release: fb_release   

9.     };   

这是面向应用程序的接口,fbmem.c中实现了这些操作。
         2) register_framebuffer(struct fb_info*fb_info) 函数 和 unregister_framebuffer(structfb_info *fb_info)函数。
        这个函数是frambuffer设备驱动程序的底层接口。驱动程序用这两个函数向内核注册和注销自己。驱动程序所做的所有底层工作就是填充一个fb_info结构体然后注册自己。




0 0
原创粉丝点击