分类: LINUX
2010-04-01 11:09:13
1 基于嵌入式Linux的GUI系统发展概况
当前流行的商业化的GUI系统包括WindowsCE和SymbianOS等。这些GUI性能出众,一般都提供完整的解决方案,对Java、多媒体的支持较好,使用它们可以很方便地构建自己的嵌入式系统,形成产品,尽可能地缩短开发周期。但这些都是商业化产品,使用它们不可避免地要付出昂贵的授权费用,没有公开源代码,用户也不能很自由地定制自己的产品。Linux的出现给嵌入式产品的开发带来了新的活力,它拥有很多的优良特性非常适合于嵌入式的开发:开放源码,拥有丰富的软件资源;健壮、强大的内核;支持多种体系结构,包括x86、ARM、MIPS等几乎所有主流的CPU;完善的网络通信、图形和文件管理机制;支持大量的周边硬件设备,驱动丰富;大小功能均可定制,充分满足嵌入式设备可定制的要求。正是由于Linux具有这么多优点,使得它在嵌入式领域取得了长足的发展,因而开发基于Linux的GUI系统就显得尤为必要。在桌面版的Linux系统中普遍采用的GUI是XWindows系统,但显然它相对于嵌入式系统来说是过于庞大了,嵌入式系统要求的是一个轻量级的性能可靠和可裁减的GUI,因此需要重新开发适合嵌入式系统的GUI。目前国内外已经推出了很多基于Linux的GUI产品,现在比较流行的一些GUI产品包括MiniGUI、MicroWindows、OpenGUI、QT Embedded等,其中QT Embedded属于商业化的产品,其他属于开源软件。从性能、功能各个方面来说QT Embedded都是一个很优秀的GUI系统,但是使用它需要支付高昂的授权费用,它一般应用在高端的PDA和SmartPhone等产品上,而其他的一些开源GUI系统,都有各自的特点和适用领域,但总体来说表现不如QT Embedded出色。
2 Framebuffer组成结构
2.1 Framebuffer简介
Framebuffer译作帧缓冲,它作为基础图形设施,是出现在Linux 2.2.XX内核当中的一种驱动程序接口,是作为其他高级图形或者图形应用程序的基本函数库。这种接口将显示设备抽象为帧缓冲区。用户可以将它看成是显示内存的一个映像而不必关 物理显存的位置、换页机制等等具体细节,这些都是由Framebuffer设备驱动来完成的,只要将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。帧缓冲区支持提高了绘图的速度和整体性能。
Framebuffer对应的源文件在Linux/drivers/video/目录下。总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。在使用帧缓冲时,Linux是将显卡置于图形模式下的。有了Framebuffer,用户的应用程序不需要对底层的驱动的深入了解就能够做出很好的图形。对于用户而言,它和/dev下面的其他设备没有什么区别,用户可以把Framebuffer看成一块内存,既可以向这块内存中写入数据,也可以从这块内存中读取数据。第一个被注册的Framebuffer的minor等于0,第二个被注册的Framebuffer的minor等于1,以此类推。
2.2 Framebuffer结构分析
Framebuffer结构分为三层,如图1。
图1 Framebuffer 结构图
最底层:基本控制台驱动程序(drivers/char/console.c),它提供了文本控制台常规接口的一部分;通过使用控制台驱动程序函数,可以将文本显示在屏幕上,但还不能显示图形或动画。
中间层:(drivers/video/fbcon.c)使用视频模式功能来实现图形或动画功能,中间层驱动程序提供了视频模式中绘图的常规接口。
顶层:是与特定硬件相关的驱动程序,它需要支持显卡不同的硬件方面,像启用/禁用显卡控制器、深度和模式的支持以及调色板等,这也是顶层驱动程序引人注意之处。所有这三层都相互依赖以实现正确的视频功能。
Linux下设备分为字符设备、块设备和网络设备接口三大类。那么Framebuffer设备属于哪一类呢?刚开始设计时容易使人困惑。其实对使用者而言, 帧缓冲设备也就是Framebufferdevice和Linux系统目录/dev下的其他设备没有区别。帧缓冲设备对应的设备文件为/dev/fb*, 如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32个,分别为/dev/fb0到/dev/fb31;而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0。当然在嵌入式系统中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0一/dev/fb31。
Framebuffer设备很大程度上依靠了下面三个数据结构。这三个结构在fb.h 中声明。
1)Struct fb_var_screeninfo:描述图形卡的特性的。通常是由用户设置的。
2)Struct fb_fix_screeninfo:定义了图形卡的硬件特性,是不能改变的,用户选定了哪一个图形卡,那么它的硬件特性也就定下来了。
3)Struct fb_info:定义了当前图形卡Framebuffer设备的独立状态,一个图形卡可能有两个Framebuffer,在这种情况下,就需要两个fb_info 结构。这个结构是唯一在内核空间可见的。
3 Framebuffer功能实现
在任何Linux嵌入式系统中,Framebuffer都发挥着极其重要的作用,没有了Framebuffer的支持,我们不可能在诸多嵌入式设备中进行图形图象的操作和显示,比如智能手机上的手写输入,家用设备的触摸感应操作等都无法完成。具体来说,Framebuffer在嵌入式Linux下有如下作用:
1)通过Framebuffer设备,可以获得显示设备的一些固定信息。(比如显示内存大小)、与显示模式相关的可变信息(比如分辨率、像素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。这些信息是通过Framebuffer提供的ioctl命令取得的,ioctl是设备驱动程序中对设备的I/O通道进行管理的函数,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等,该函数调用如下:int ioctl(int fd,ind cmd,……);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关。
2)通过Framebuffer设备获得当前内核所支持的加速显示卡的类型(通过固定信息得到)。这种类型通常是和特定显示芯片相关的。获得了加速芯片类型之后,应用程序就可以将显卡内存I/O(称为memio)映射到进程的地址空间。这些memio一般是用来控制显示卡的寄存器,通过对这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。
3)显示设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问,给变成了对物理内存的访问。一旦被映射到物理内存,Linux的普通进程才可以通过映射操作(mmap)将这些内存I/O 映射到进程地址空间,这样就可以直接访问这些寄存器。
在支持Framebuffer的嵌入式设备中,应用程序都可以对Framebuffer进行操作,操作包括:
1)读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区;
2)映射(mmap)操作:Linux通过文件操作file_operations结构中提供的mmap函数映射操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区在屏幕上绘图。若干个进程可以映射到同一个显示缓冲区。实际上,使用帧缓冲设备的应用程序都是通过映射操作来显示图形的。由于映射操作都是由内核来完成,帧缓冲驱动留给开发人员的工作并不多。
3)I/O控制:通过ioctl操作完成。
在屏幕上绘图Framebuffer中内存块分布如图2所示。
图2 内存块分布图
4 Linux下利用Framebuffer实现直接写屏
4.1支持Framebuffer的Linux内核编译
在Linux下实现Framebuffer的编程之前,也需要对其进行内核编译,生成支持Framebuffer的内核,编译内核的方法和传统的方法一样,但也有一些不同,应以root(管理员)身份登陆Linux。编译完之后重起系统,选择进入自己编译生成的内核模式,但要注意的是,在登陆之前要对“linuxvga”进行设置,设置成符合Framebuffer的工作模式,比如设置“linuxvga=771”即进入800*600*256色的工作模式。登陆后看到启动页面上出现小企鹅的图像则说明已经成功登陆支持Framebuffer的内核模式,启动完毕后再以root身份登陆,即进入支持Framebuffer的内核模式,现在就可以在此终端下进行相应的Framebuffer编程了。
4.2 Framebuffer的应用编程
基于Framebuffer的Linux内核编译完后,就可以在Linux下进行相应的功能编程。但是最常用以及最有代表性的应用是Linux下通过Framebuffer的直接写屏。该技术已经应用到智能手机、PDA及其他嵌入式设备中,如PDA上的手写输入功能。下面其实现的具体流程。在实际编程当中,应用程序对Framebuffer的具体操作流程如下:
1)打开/dev/fb设备文件;
2)用ioctrl操作取得当前显示屏幕的参数,如屏幕分辨率,每个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。
3)将屏幕缓冲区映射到用户空间。
4)映射后就可以直接读写屏幕缓冲区,进行绘图和图片显示了。
在内核编译以及初始化设置完成之后,我们基于上述操作,在Linux下运行用C语言编写的Framebuffer实现直接写屏程序,我们看到在Linux系统桌面上,我们可以用鼠标直接进行写汉字及绘图操作,将之应用到PDA、智能手机以及其他嵌入式设备上,则就可实现手写输入功能。
当然,利用Framebuffer进行的操作和实现的功能还有很多,作为硬件图形接口,通过Framebuffer,才可实现对底层硬件设备的操作,最具有代表性的就是实现图形操作,并在应用层上进行显示。
5 结束语
嵌入式GUI是介于嵌入式操作系统和上层应用程序之间的中间产品,对于基于Linux操作系统的嵌入式系统解决方案来说,在操作系统这一级上各个厂家区别不大,因此GUI的优劣对于一个产品来说就显得尤为重要。Framebuffer作为基础图形设施,把显存抽象成一种设备,通过对此设备的读写直接对显存进行操作,因此它是用户进入图形界面很好的接口,这极大地帮助用户能够设计出高性能的GUI,从而既满足了用户的较高需求,又使自己的嵌入式产品具有极强的竞争力。随着嵌入式技术的进一步发展和广泛应用,Frambufer在嵌入式GUI系统中必将发挥出越来越重要的作用。