图形用户界面 实验报告二
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图形用户接口
081180015 戴稚晖通信工程
一、实验目的
1、了解嵌入式系统图形用户界面的基本编程方法。
2、探讨软件结构的层次关系,学习图形库的制作。
一、实验原理概述
1、图形用户界面简介
图形用户界面(GUI)是一种图形化为基础的用户界面,使用统一的图形操作方式,如可移动的视图,选项及鼠标,作为用户与操作系统之间的桥梁,从而使用
户摆脱了在命令行提示符下与操作系统进行交互的方式。
在嵌入式系统设计中,常被选择作为GUI系统进行开发的有:MiniGUI、MicroWindows、OpenGUI和QT/Embedded。这些GUI系统都是以Frame Buffer作为
图形驱动。Frame Buffer作为Linux内核提供的一种底层图形接口,将显示设备
映射到进程地址空间,是大多数GUI的基础。
2、Frame Buffer简介
Frame Buffer又称之为帧缓冲或显存,是系统内的一段存储空间,与显示屏的整个显示区域相对应,通过改变帧缓冲区的内容来改变显示信息。
Frame Buffer的空间大小由显示屏的大小和显示模式决定。显示屏可以以单色或者彩色显示,单色用一位来表示颜色,彩色可以用2、4、8、16、24、32等位
色。显示屏有单屏和双屏显示模式。其中双屏显示模式将整个屏幕分为两部分,每
个部分有各自的Frame Buffer,它们的地址无需连续,并有独立的两个通道将Frame Buffer中的数据传输到显示屏。
3、Frame Buffer与图像色彩
Frame Buffer支持多种颜色显示方式:单色,伪彩色,真彩色,直接色,灰度。伪彩色的RGB值不能直接从Frame Buffer中得到,而是通过调色板间接得到,
此时Frame Buffer中存放的是调色板的索引值,通过索引值获得颜色。真彩色的
RGB值直接从Frame Buffer中得到,且不需要经过调色板。直接彩色Frame Buffer
里存放的是RGB值,但需要经过调色板调色后传输到显示屏。
在16为/像素模式下,Frame Buffer里的每个单元为16位,其中前五位是R 值,中间六位是G值,后五位是B值。
4、LCD控制器——Frame Buffer与显示屏之间的接口
LCD控制器是Frame Buffer与显示屏之间的一个中间部件,负责从Frame Buffer中提取数据,进行处理,并传输到显示屏上。本实验用到的开发板处理器
PXA270集成了LCD控制器,实验中用到的显示屏是16位的TFT LCD,像素分辨率
为 640×480。
二、实验过程
1、内核对Frame Buffer的支持,内核配置选项的修改
在内核源码所在目录下make menuconfig————在Console drivers(终端设备驱动设置)中选中“support for frame buffer devices(EXPERIMENTAL)”
和“PXA LCD support”—————在Multimedia drivers中选中UCB 1400
Touchscreen support on the xsBase 270 Board,在其下的GUI to be supprted
中选择Qtopia而不是用tinyx————在Frame buffer support 中选择Virtual
Frame Support。
2、Frame Buffer操作
Frame Buffer在系统中是以设备文件的形式体现的,在/dev下可以看到fb,fb0,fb1或者更多。打开Frame Buffer与打开一般的文件一样,
fd=open(“/dev/fb”,O_RDWR)。还可以用cp /dev/fb0 file1对屏幕进行抓拍。
Frame Buffer为应用程序提供了良好的用户接口。可以用ioctl命令来获得Frame Buffer的一些参数,如:可以用structfb_fix_screeninfofinfo;
ioctl(fd,FBIOGET_FSCREENINFO,&finfo)来获取它的的固有参数;用
structfb_var_screeninfovinfo ;ioctl(fd,FBIOGET_VSCREENINFO,&vinfo)来获
取它的可变参数,其中包括显示器的色位,分辨率等信息(vinfo.bits_per_pixel、vinfo.xres、vinfo.yres)。
如何获得显示缓冲区的内存映射地址。使用系统调用函数mmap(),获得缓冲区首地址。调用方式为:unsigned char *fbp=0;screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;fbp=( un signed char *)mman(0,sreensize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);结束缓冲区使用后要用munmap(fbp,screensize)将内存空间释放。用memset (fbp,0,sreensize)可以实现清屏(黑色)操作,将数字0改成255可以实现白屏操作。
在编写程序时,将上面获取显示屏可变参数和获取缓冲区首地址的语句组合起来,编写成初始化函数。将释放缓冲区内存的语句编写成结束函数,将清屏语句编写成清屏函数,以供主函数调用。
3、在Frame Buffer上画点画线画圆的API函数
画点函数。由于显示屏用的是16位色,要将RGB压缩成16位,再填充其字节下面是画点函数的程序段:
Void draw_point(intx,inty,intred,intgreen,int blue)
{intcolor,offset;
offset=(y*vinfo.xres+x)*vinfo.bits_per_pixel/8;
color=(red<<11)|(green<<5&0x07E0)|(blue&0x1F);
*(unsigned char *)(fbp+offset+0)=color&0xFF;
*(unsigned char *)(fbp+offset+1)=(color>>8)&0xFF;
}//实现了在任意地方画任意颜色的点
画线函数:实验中我编写的画线函数使用任意颜色可以画任意两点之间的直线段,在函数中调用了画点函数。画线函数的形式是:void draw_line(int x1,int y1,int x2,int y2,int red,intgreen,int blue)。画线程序编写过程中,考虑到显示屏的扫描是从第一行到最后一行,第一列到最后一列,然后进行回扫,我在编写过程中想到,要想一帧扫描时画的点更多,或者说总共画线过程花的时间较少,在画直线程序中应该比较一下两点之间的横坐标大小,从横坐标小的点开始画。由于程序段显得有些长,在这里只是说明一下编程思想。先比较两点横坐标的大小,