帧缓冲(framebuffer)是linux系统显示设备的框架,将显示缓冲区抽象,屏蔽具体细节,用户可以直接操作帧缓冲,达到显示的目的。
常见的xwindow和qte也是基于帧缓冲而搭建,只需将图形的颜色值写入帧缓冲对应点,就能达到具体的显示效果。在嵌入式linux系统中,
LCD驱动都是基于framebuffer框架,以达到轻量级的图形接口。
帧缓冲设备是标准的字符设备,对应主设备号位29,设备节点为/dev/fb*,最大支持32个设备。帧缓冲与像素点的具体关系根据色彩位不同而不同,
常见的RGB565,对应一个short int 型,低5位为BULE,中间6位为GREEN,高5位为RED。
既然帧缓冲设备是一种字符设备,那必然存在一个file_operation结构,该结构在drivers/video/fbmem.c中,编写驱动时不用关心,只需注册一个
帧缓冲设备的struct fb_info信息即可。
819 struct fb_info {
820 int node;
821 int flags;
822 struct mutex lock; /* Lock for open/release/ioctl funcs */
823 struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */
824 struct fb_var_screeninfo var; /* Current var*/
825 struct fb_fix_screeninfo fix; /* Current fix */
/* fb_var_screeninfo和fb_fix_screeninfo是驱动程序中最重要的,这是与LCD驱动器相关的参数,分为可变的参数和不可变参数 */
826 struct fb_monspecs monspecs; /* Current Monitor specs */
827 struct work_struct queue; /* Framebuffer event queue */
828 struct fb_pixmap pixmap; /* Image hardware mapper */
829 struct fb_pixmap sprite; /* Cursor hardware mapper */
830 struct fb_cmap cmap; /* Current cmap */
/* fb_cmap,是当前的颜色表 大于16BPP的不使用该字段*/
831 struct list_head modelist; /* mode list */
832 struct fb_videomode *mode; /* current mode */
833
834 #ifdef CONFIG_FB_BACKLIGHT /* 背光控制*/
835 /* assigned backlight device */
836 /* set before framebuffer registration,
837 remove after unregister */
838 struct backlight_device *bl_dev;
839
840 /* Backlight level curve */
841 struct mutex bl_curve_mutex;
842 u8 bl_curve[FB_BACKLIGHT_LEVELS];
843 #endif
844 #ifdef CONFIG_FB_DEFERRED_IO
845 struct delayed_work deferred_work;
846 struct fb_deferred_io *fbdefio;
847 #endif
848
849 struct fb_ops *fbops; /* 这是帧缓冲设备的操作函数集,根据具体的硬件实现,很重要的结构 */
850 struct device *device; /* This is the parent */
851 struct device *dev; /* This is this fb device */
852 int class_flag; /* private sysfs flag */
854 struct fb_tile_ops *tileops; /* Tile Blitting */
855 #endif
856 char __iomem *screen_base; /* Virtual address */
857 unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */
/* screen_base,screen_size是帧缓冲映射后的虚拟地址和大小,这个地址并不是帧显示的地址*/
858 void *pseudo_palette; /* Fake palette of 16 colors */
859 #define FBINFO_STATE_RUNNING 0
860 #define FBINFO_STATE_SUSPENDED 1
861 u32 state; /* Hardware state i.e suspend */
862 void *fbcon_par; /* fbcon use-only private area */
863 /* From here on everything is device dependent */
864 void *par;
865 /* we need the PCI or similiar aperture base/size not
866 smem_start/size as smem_start may just be an object
867 allocated inside the aperture so may not actually overlap */
868 resource_size_t aperture_base;
869 resource_size_t aperture_size;
870 };
struct fb_info 记录一个帧缓冲设备的所有信息,一个设备对应一个fb_info结构题,通过register_framebuffer向帧换冲框架注册。
int register_framebuffer(struct fb_info *fb_info);
fb_var_screeninfo 结构体记录着用户可以修改的设备参数,具体如下:
237 struct fb_var_screeninfo {
238 __u32 xres; /* visible resolution */
239 __u32 yres;
/* 可见的分辨率,比如800*480的7寸屏,800*480是可见的,但实际会比这个大,用户同步和消隐 */
240 __u32 xres_virtual; /* virtual resolution */
241 __u32 yres_virtual;
/* 对应虚拟的分辨率 */
242 __u32 xoffset; /* offset from virtual to visible */
243 __u32 yoffset; /* resolution */
244 /* 虚拟到可见的偏移,如果xres 和xres_virtual相等,那么该段为0 */
245 __u32 bits_per_pixel; /* guess what */
/* 每个像素点位宽,比如RGB565这个就应该是16;
246 __u32 grayscale; /* != 0 Graylevels instead of colors */
247 /* 表示灰度 */
248 struct fb_bitfield red; /* bitfield in fb mem if true color, */
249 struct fb_bitfield green; /* else only length is significant */
250 struct fb_bitfield blue;
251 struct fb_bitfield transp; /* transparency */
252
253 __u32 nonstd; /* != 0 Non standard pixel format */
254
255 __u32 activate; /* see FB_ACTIVATE_* */
256
257 __u32 height; /* height of picture in mm */
258 __u32 width; /* width of picture in mm */
259
260 __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
261
262 /* Timing: All values in pixclocks, except pixclock (of course) */
263 __u32 pixclock; /* pixel clock in ps (pico seconds) */
/* 像素时钟,单位是皮秒1s=10^-12ps */
264 __u32 left_margin; /* time from sync to picture */
/* 从同步到绘图之间的延时,或者叫水平后沿 */
265 __u32 right_margin; /* time from picture to sync */
/* 水平前沿 */
266 __u32 upper_margin; /* time from sync to picture */
/* 垂直后沿 */
267 __u32 lower_margin;
/* 垂直前沿 */
268 __u32 hsync_len; /* length of horizontal sync */
269 __u32 vsync_len; /* length of vertical sync */
/* 水平,垂直同步长度,即在水平后沿和垂直后沿前面的同步时钟长度 */
/* 以上所有同步时间,都是以像素时钟作为单位,即同步时间=同步宽度*pixclock */
270 __u32 sync; /* see FB_SYNC_* */
271 __u32 vmode; /* see FB_VMODE_* */
272 __u32 rotate; /* angle we rotate counter clockwise */
273 __u32 reserved[5]; /* Reserved for future compatibility */
274 };
以上是可变参数结构,另外还有struct fb_fix_screeninfo不可变参数:
154 struct fb_fix_screeninfo {
155 char id[16]; /* identification string eg "TT Builtin" */
156 unsigned long smem_start; /* Start of frame buffer mem */
157 /* (physical address) */
/* 这个才是fb的真正缓冲地址,用户空间写的颜色值是写在这个地址开始的空间的 */
158 __u32 smem_len; /* Length of frame buffer mem */
/* 长度 = 调色板 + 像素点*位宽
159 __u32 type; /* see FB_TYPE_* */
160 __u32 type_aux; /* Interleave for interleaved Planes */
161 __u32 visual; /* see FB_VISUAL_* */
/* 使用的色彩,包括黑白,白黑,伪彩,真彩等,常使用的真彩即原始数据就是颜色,不需要在查表索引转换 */
162 __u16 xpanstep; /* zero if no hardware panning */
163 __u16 ypanstep; /* zero if no hardware panning */
164 __u16 ywrapstep; /* zero if no hardware ywrap */
165 __u32 line_length; /* length of a line in bytes */
/* 行像素点* 位宽 800*480,16BPP: line_length=800 * 2 */
166 unsigned long mmio_start; /* Start of Memory Mapped I/O */
167 /* (physical address) */
168 __u32 mmio_len; /* Length of Memory Mapped I/O */
169 __u32 accel; /* Indicate to driver which */
170 /* specific chip/card we have */
171 __u16 reserved[3]; /* Reserved for future compatibility */
172 };
完成这三个结构体,一个framebuffer设备驱动框架就完成了,如此针对具体控制器的驱动流程如下:
1.申请fb_info,填充fb_var_screeninfo和fb_fix_screeninfo
2.完成LCD控制器初始化,即时序的配置
3.注册帧缓冲设备