Framebuffer 驅動學習總結(一) ---- 整體架構及關鍵結構體

1、Framebuffer 設備驅動整體架構node

幀緩衝設備爲標準的字符型設備,在Linux中主設備號29,定義在/include/linux/major.h中的FB_MAJOR,次設備號定義幀緩衝的個數,最大容許有32個FrameBuffer,定義在/include/linux/fb.h中的FB_MAX,對應於文件系統下/dev/fb%d設備文件。linux

 

 

咱們從上面這幅圖看,幀緩衝設備在Linux中也能夠看作是一個完整的子系統,大致由fbmem.c和xxxfb.c組成。向上給應用程序提供完善的設備文件操做接口(即對FrameBuffer設備進行read、write、ioctl等操做),接口在Linux提供的fbmem.c文件中實現;向下提供了硬件操做的接口,只是這些接口Linux並無提供實現,由於這要根據具體的LCD控制器硬件進行設置,因此這就是咱們要作的事情了(即xxxfb.c部分的實現)。緩存

二 、Framebuffer 相關的重要數據結構:數據結構

一、從Framebuffer設備驅動程序結構看,該驅動主要跟fb_info結構體有關,該結構體記錄了Framebuffer設備的所有信息,包括設備的設置參數、狀態以及對底層硬件操做的函數指針。在Linux中,每個Framebuffer設備都必須對應一個fb_info,fb_info在/linux/fb.h中的定義以下:(只列出重要的一些) 架構

 1 struct fb_info {
 2     atomic_t count;
 3     int node; ///次設備號
 4     int flags;
 5     struct mutex lock;  //用於open、release、ioctrl功能的鎖
 6     struct mutex mm_lock;  /* Lock for fb_mmap and smem_* fields */
 7     struct fb_var_screeninfo var;  //LCD 可變參數
 8     struct fb_fix_screeninfo fix;   //LCD 固定參數
 9     struct fb_monspecs monspecs;   /* Current Monitor specs *///LCD 顯示器標準
10     struct work_struct queue;   //幀緩衝事件隊列
11     struct fb_pixmap pixmap;   ///圖像硬件 mapper
12     struct fb_pixmap sprite;   //光標硬件 mapper
13     struct fb_cmap cmap;     //當前顏色表
14     struct list_head modelist;   //模式列表
15     struct fb_videomode *mode;   //當前的顯示模式
16 
17 #ifdef CONFIG_FB_BACKLIGHT
18     /* assigned backlight device */
19     /* set before framebuffer registration, 
20        remove after unregister */
21     struct backlight_device *bl_dev;///對應的背光設備
22 
23     /* Backlight level curve */
24     struct mutex bl_curve_mutex;    
25     u8 bl_curve[FB_BACKLIGHT_LEVELS];///背光調整
26 #endif
27 #ifdef CONFIG_FB_DEFERRED_IO
28     struct delayed_work deferred_work;
29     struct fb_deferred_io *fbdefio;
30 #endif
31 
32     struct fb_ops *fbops;///---->對底層硬件設備操做的函數指針
33     struct device *device;     /* This is the parent *////父設備節點
34     struct device *dev;      /* This is this fb device *////當前的幀緩衝設備
35     int class_flag;               /* private sysfs flags */
36 #ifdef CONFIG_FB_TILEBLITTING
37     struct fb_tile_ops *tileops;  /* Tile Blitting *///圖塊Blitting ?
38 #endif
39     char __iomem *screen_base;   /* Virtual address *///虛擬地址
40     unsigned long screen_size;   /* Amount of ioremapped VRAM or 0 */ ///LCD IO映射的虛擬內存大小
41     void *pseudo_palette;       /* Fake palette of 16 colors *///僞16色 顏色表
42 #define FBINFO_STATE_RUNNING   0
43 #define FBINFO_STATE_SUSPENDED   1
44     u32 state;            /* Hardware state i.e suspend *////LCD 掛起或復位的狀態
45     void *fbcon_par;                /* fbcon use-only private area */
46     /* From here on everything is device dependent */
47     void *par;
48     /* we need the PCI or similar aperture base/size not
49        smem_start/size as smem_start may just be an object
50        allocated inside the aperture so may not actually overlap */
51     struct apertures_struct {
52         unsigned int count;
53         struct aperture {
54             resource_size_t base;
55             resource_size_t size;
56         } ranges[0];
57     } *apertures;
58 
59     bool skip_vt_switch; /* no VT switch on suspend/resume required */
60 };

其中,fb_var_screeninfo和fb_fix_screeninfo兩個結構體跟LCD硬件屬性相關,fb_var_screeninfo表明可修改的LCD顯示參數,如分辨率和像素比特數;fb_fix_screeninfo表明不可修改的LCD屬性參數,如顯示內存的物理地址和長度等。另一個很是重要的成員是fb_ops,其是LCD底層硬件操做接口集。app

         fb_ops硬件操做接口集包含不少接口,如設置可變參數fb_set_par、設置顏色寄存器fb_setcolreg、清屏接口fb_blank、畫位圖接口fb_imageblit、內存映射fb_mmap等等。ide

         fb_info結構體在調用register_framebuffer以前完成初始化。通常來講,LCD設備屬於平臺設備,其初始化是在平臺設備驅動的probe接口完成。而LCD設備所涉及的硬件初始化則在平臺設備初始化中完成。函數

 

二、fb_fix_screeninfo結構體主要記錄用戶不能夠修改的控制器的參數,該結構體的定義以下:佈局

 1 struct fb_fix_screeninfo {
 2     char id[16];            //字符串形式的標識符
 3     unsigned long smem_start;   /fb 緩存的開始位置
 4                     /* (physical address) */
 5     __u32 smem_len;            /* Length of frame buffer mem *///fb 緩存的長度
 6     __u32 type;            /* see FB_TYPE_*        *////看FB_TYPE_* -->
 7     __u32 type_aux;            /* Interleave for interleaved Planes *///分界
 8     __u32 visual;             ///看FB_VISUAL_* -->
 9     __u16 xpanstep;         //若是沒有硬件panning就賦值爲0
10     __u16 ypanstep;            //若是沒有硬件panning就賦值爲0
11     __u16 ywrapstep;        //若是沒有硬件ywrap就賦值爲0
12     __u32 line_length;        //一行的字節數
13     unsigned long mmio_start;   //內存映射 IO的開始位置
14                     /* (physical address) */
15     __u32 mmio_len;            //內存映射 IO的長度
16     __u32 accel;            /* Indicate to driver which    */
17                     /*  specific chip/card we have    */
18     __u16 capabilities;        /* see FB_CAP_*            *///功能 ---FB_CAP_FOURCC--- Device supports FOURCC-based formats
19     __u16 reserved[2];       //爲之後的兼容性保留
20 };

 

三、fb_var_screeninfo結構體主要記錄用戶能夠修改的控制器的參數,好比屏幕的分辨率和每一個像素的比特數等,該結構體定義以下:ui

 1 struct fb_var_screeninfo { ///顯示屏信息
 2     __u32 xres;            /* visible resolution*//可視區域,一行有多少個像素點
 3     __u32 yres;            ///可視區域,一列有多少個像素點
 4     __u32 xres_virtual;  /* virtual resolution*//虛擬區域,一行有多少個像素點,簡單的意思就是內存中定義的區間是比較大的
 5     __u32 yres_virtual;////虛擬區域,一列有多少個像素點
 6     __u32 xoffset;            //虛擬到可見屏幕之間的行偏移
 7     __u32 yoffset;            /* resolution *//虛擬到可見屏幕之間的列偏移
 8 
 9     __u32 bits_per_pixel; /* guess what*/ 每一個像素的 bit 數,這個參數不須要本身配置,而是經過上層在調用 checkvar 函數傳遞 bpp 的時候賦值的
10     __u32 grayscale;        /* 0 = color, 1 = grayscale,*////等於零就成黑白 (灰度)
11                     /* >1 = FOURCC            */
12     // 經過 pixel per bpp 來設定 red green 和 blue 的位置; pixel per bpp 能夠經過 ioctl 設定
13     struct fb_bitfield red;        //fb緩存的R位域
14     struct fb_bitfield green;    /* else only length is significant *//fb緩存的G位域
15     struct fb_bitfield blue;                                        //fb緩存的B位域
16     struct fb_bitfield transp;    /* transparency *//透明度
17 
18     __u32 nonstd;            /* != 0 Non standard pixel format *///若是nonstd 不等於0,非標準的像素格式
19 
20     __u32 activate;            /* see FB_ACTIVATE_*     */
21 
22     __u32 height;         //內存中的圖像高度
23     __u32 width;        //內存中的圖像寬度
24 
25     __u32 accel_flags;        /* (OBSOLETE) see fb_info.flags *////加速標誌
26 
27     /* Timing: All values in pixclocks, except pixclock (of course) */
28     ///時序,這些部分就是顯示器的顯示方法了,和具體的液晶顯示屏有關,在驅動中通常放在 具體液晶屏的配置文件 
29     __u32 pixclock;            /* pixel clock in ps (pico seconds) *///像素時鐘
30     __u32 left_margin;        /* time from sync to picture    *////行切換,從同步到繪圖之間的延遲
31     __u32 right_margin;        /* time from picture to sync    *///行切換,從繪圖到同步之間的延遲
32     __u32 upper_margin;        /* time from sync to picture    *///幀切換,從同步到繪圖之間的延遲
33     __u32 lower_margin;                                        ////幀切換,從繪圖到同步之間的延遲
34     __u32 hsync_len;        /* length of horizontal sync    */ //水平同步的長度
35     __u32 vsync_len;        /* length of vertical sync    */ //垂直同步的長度
36     __u32 sync;            /* see FB_SYNC_*      *////---->看 FB_SYNC_*
37     __u32 vmode;            /* see FB_VMODE_*      *////---->看 FB_VMODE_*
38     __u32 rotate;            /* angle we rotate counter clockwise */
39     __u32 colorspace;        /* colorspace for FOURCC-based modes */
40     __u32 reserved[4];        /* Reserved for future compatibility */
41 };

 經過下圖能夠對fb_var_screeninfo中涉及的時序理解更清楚一些:

 

四、fb_ops結構體是對底層硬件操做的函數指針,該結構體中定義了對硬件的操做有:

注: fb_ops結構與file_operations 結構不一樣,fb_ops是底層操做的抽象,file_operations是提供給上層系統調用的接口,能夠直接調用.

 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);
/*對於非線性佈局的/常規內存映射沒法工做的幀緩衝設備須要*/  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); 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);///檢查可變參數並進行設置 19 /* set the video mode according to info->var */ 20 int (*fb_set_par)(struct fb_info *info);///根據設置的值進行更新,使之有效 22 /* set color register */ 23 int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, ////設置顏色寄存器 24 unsigned blue, unsigned transp, struct fb_info *info); 26 /* set color registers in batch */ 27 int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
29 30 int (*fb_blank)(int blank, struct fb_info *info);///顯示空白 32 /*pan顯示*/ 33 int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); 36 void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);///矩形填充 38 void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);///複製數據 40 void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);///圖形填充 42 /* 繪製光標 */ 43 int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor); 45 /* 旋轉顯示 */ 46 void (*fb_rotate)(struct fb_info *info, int angle); 48 /* 等待blit空閒 */ 49 int (*fb_sync)(struct fb_info *info); 51 /* fb 特定的 ioctl */ 52 int (*fb_ioctl)(struct fb_info *info, unsigned int cmd, 53 unsigned long arg); 55 /* 處理32bit compat ioctl (optional) */ 56 int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd, 57 unsigned long arg); 59 /* fb 特定的 mmap */ 60 int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); 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); 66 /* teardown any resources to do with this framebuffer */ 67 void (*fb_destroy)(struct fb_info *info); 69 /* called at KDB enter and leave time to prepare the console */ 70 int (*fb_debug_enter)(struct fb_info *info); 71 int (*fb_debug_leave)(struct fb_info *info); 72 };

 

五、fb_cmap:設備獨立的 colormap 信息,能夠經過 ioctl 的 FBIOGETCMAP 和 FBIOPUTCMAP 命令設置 colormap;

struct fb_cmap { //顏色映射表
    __u32 start;            /* First entry    *////第一個入口
    __u32 len;            /* Number of entries *///入口的數字
    __u16 *red;            /* Red values    *///紅色
    __u16 *green;                        ///綠色
    __u16 *blue;                        ///藍色
    __u16 *transp;           //透明度,容許爲空
};

 

這些結構相互之間的關係以下所示:

相關文章
相關標籤/搜索