您的位置:首页 > Web前端

microwindows代码分析 (四)screen driver显示驱动之framebuffer

2008-07-15 22:48 621 查看
转载时请注明出处和作者联系方式:http://blog.csdn.net/mimepp
作者联系方式:YU TAO <yut616 at sohu dot com>

microwindows代码分析 (四)screen driver显示驱动之framebuffer

关键字:microwindows, microwin, 代码, 分析, framebuffer

在microwindows的显示驱动中,一个很重要的部分就是framebuffer的驱动,framebuffer已经在大量的嵌入式设备中都被支持,所以有了framebuffer,microwindows就可被移植到很多的嵌入式设备中了。

framebuffer的驱动代码是放在了drivers/scr_fb.c里。
在drivers/Makefile中,如果FRAMEBUFFER=Y,那么scr_fb.o会被编译到microwindows的driver代码中。

和X11方式的类似,scr_fb.c也定义了一个全局变量:
SCREENDEVICE    scrdev;
其中就包含了需要为framebuffer而实现的接口函数,如fb_open,fb_close,gen_getscreeninfo,fb_mapmemgc等。
这些都是SCREENDEVICE结构中各个函数的具体实现,从而给上层的microwindows画图函数提供了统一的函数接口。

现在我们来看一下fb有关的函数。
在fb_open中,会现从环境变量中读取FRAMEBUFFER的内容,看是否外部已经有所指定:
if(!(env = getenv("FRAMEBUFFER")))
env = "/dev/fb0";
fb = open(env, O_RDWR);
然后会用open打开这个fd。
然后会使用ioctl来和kernel的framebuffer交互,得到FBIOGET_FSCREENINFO(fixed),FBIOGET_VSCREENINFO (variable)设备信息,即固定的屏幕信息,还有可变的屏幕信息。
第一个固定的屏幕信息,它由硬件和驱动的能力决定。
第二个是可变的屏幕信息,它由硬件的当前状态决定,它是可以让用户空间的程序调用ioctl来改变的。
struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
大家可以查看上面的两个结构,来获得其中的详细定义。

它里面比较有用的信息,就是
fb_fix.type;   --- 表示planes类型,如0为象素
fb_fix.visual; --- 表示视觉类型,如真彩2,伪彩3
fb_var.bits_per_pixel; --- 表示bpp
fb_fix.line_length; --- 表示每行长度
然后在后面的代码,也会出新要设置 sub driver的内容:
subdriver = select_fb_subdriver(psd);
set_subdriver(psd, subdriver, TRUE)
这里是对psd来设置sub driver的,所以在sub driver中的各种draw pixel就会将之前的函数所覆盖。也即scr_fb的很多pixel相关函数,会转到sub driver中。

下面的部分就是要做一个framebuffer到内存地址的映射,即mmap:
/* mmap framebuffer into this address space*/
psd->size = (psd->size + getpagesize () - 1)
/ getpagesize () * getpagesize ();
psd->addr = mmap(NULL, psd->size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
在这里,psd->size做了一个按page对齐的转换。
mmap的作用是映射后,就不需要再去read,write文件,这样就避免大量的寻址的开销,所以将framebuffer映射到一个内存上,这样应用直接访问内存效率会高很多。
mmap并不分配空间,只是将文件映射到调用进程的地址空间里。
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
mmap的第四个变量表示这个内存和其他进程的共享情况
需要特别指出的是,在uclinux系统中,这里不能使用MAP_SHARED,而只能使用
#define MAP_FIXED	0x10		/* Interpret addr exactly.  */
即如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。
因为uclinux是无MMU管理的,内存的访问是直接访问物理地址的,所以它是不能与其他进程共享一个内存的。

fb_open即完成了主要的工作,其他部分的内容,主要是处理一些特殊情况的framebuffer的操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: