17.2.2 虚拟帧缓冲驱动
《嵌入式Linux系统开发全程解析》是一本全面介绍嵌入式Linux开发的专著,书中涵盖了程序生成工具、调试工具、引导加载器、Linux系统结构、Linux内核、驱动程序、用户空间编程、用户空间中间件等方面的内容。《嵌入式Linux系统开发全程解析》内容前后照应、贴近实践,且有较强的延伸型,有利于读者建立嵌入式Linux开发系统化的知识结构和技术理念。本节为大家介绍虚拟帧缓冲驱动。
17.2.2 虚拟帧缓冲驱动
虚拟帧缓冲(vfb,Virtual FrameBuffer)驱动程序是一个不基于硬件的驱动程序,它在内存中开辟虚拟显示设备的内存,这可以模拟对显示的操作。
从结构上,vfb和一个真实的显示驱动程序基本相同,但是它实际上并不完成显示的功能,而只提供虚拟显示输出功能。在实际的系统中,vfb通常仅仅用于测试,或者在没有支持FrameBuffer硬件的时候,作为默认的实现。
虚拟帧缓冲驱动的源代码为:drivers/video/vfb.c。
在内核配置的时候,如果选择了虚拟帧缓冲的支持(FB_VIRTUAL),将会自动选择帧缓冲驱动的几个配置宏(填充、区域复制、fb的sys文件系统)。
vfb变化屏幕信息(fb_var_screeninfo)的定义如下所示:
- static struct fb_var_screeninfo vfb_default __initdata = {
- .xres = 640, .yres = 480, // 定义屏幕的大小
- .xres_virtual = 640, .yres_virtual = 480,
- .bits_per_pixel = 8,
- .red = { 0, 8, 0 }, // 定义RGB888的颜 {MOD}空间
- .green = { 0, 8, 0 },
- .blue = { 0, 8, 0 },
- .activate = FB_ACTIVATE_TEST,
- .height = -1, .width = -1,
- .pixclock = 20000,
- .left_margin = 64, .right_margin = 64,
- .upper_margin = 32, .lower_margin = 32,
- .hsync_len = 64, .vsync_len = 2,
- .vmode = FB_VMODE_NONINTERLACED,
- };
vfb_default结构的定义表示vfb的屏幕大小为640×480,颜 {MOD}空间为RGB888,每个像素24个字节。
vfb固定屏幕信息(fb_fix_screeninfo)的定义如下所示:
- static struct fb_fix_screeninfo vfb_fix __devinitdata = {
- .id = "Virtual FB",
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .xpanstep = 1,// 虚拟的屏幕可以支持任意的移位操作
- .ypanstep = 1,
- .ywrapstep = 1,
- .accel = FB_ACCEL_NONE,
- };
vfb的FrameBuffer操作由vfb_ops结构表示,内容如下所示:
- static struct fb_ops vfb_ops = {
- .fb_read = fb_sys_read,
- .fb_write = fb_sys_write,
- .fb_check_var = vfb_check_var, // vfb的检查参数
- .fb_set_par = vfb_set_par, // vfb的设置参数
- .fb_setcolreg = vfb_setcolreg, // vfb的设置颜 {MOD}寄存器
- .fb_pan_display = vfb_pan_display, // vfb的移动操作
- .fb_fillrect = sys_fillrect,
- .fb_copyarea = sys_copyarea,
- .fb_imageblit = sys_imageblit,
- .fb_mmap = vfb_mmap, // vfb的内存映射操作
- };
在vfb_ops结构中的sys_fillrect(填充矩形)、sys_copyarea(复制区域)和sys_imageblit(绘制图像)是FrameBuffer驱动程序中公用的函数,而以vfb_为前缀的几个函数是在vfb驱动中单独实现的。
vfb_pan_display()的实现如下所示:
- static int vfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
- {
- if (var->vmode & FB_VMODE_YWRAP) {
- if (var->yoffset < 0
- || var->yoffset >= info->var.yres_virtual || var->xoffset)
- return -EINVAL;
- } else {
- if (var->xoffset + var->xres > info->var.xres_virtual ||
- var->yoffset + var->yres > info->var.yres_virtual)
- return -EINVAL;
- }
- info->varvar.xoffset = var->xoffset; // 指定显示的位置
- info->varvar.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- info->var.vmode |= FB_VMODE_YWRAP;
- else
- info->var.vmode &= ~FB_VMODE_YWRAP;
- return 0;
- }
vfb_pan_display()利用了虚拟缓冲完成显示区域调整的函数。在其中,并不需要完全重写显示区域,只需要将可以显示区域的地址赋值。
提示:在一个实际的硬件系统中,pan功能的实现应当实际显示硬件的寄存器操作。