转载请注明作者及网址
Frame Buffer的本意帧缓冲。它是指显示设备里的显存。显存里保存是像素的RGB数据。一个显存的大小,屏幕宽度*屏幕高度*每像素字节数。
软件修改显存的像素值,就形成各种显示效果.再由硬件将显存数据送到显示模块输出。显存一般是由SDRAM一段连续的空间来充当。
Linux一般都把FB设备当成显示设备标准接口。它的设备结点 /dev/fbn表示。比如第一个FB设备是/dev/fb0.应用程序通过一组标准IOCTL来操作FB驱动。
fbset就是查询FB驱动的一命令行工具,以下是执行实例
[root@hxy /]# fbset
mode "480x272-1"
# D: 0.111 MHz, H: 0.211 kHz, V: 0.739 Hz
geometry 480 272 480 272 16
timings 9009000 2 2 2 2 41 10
accel false
rgba 5/11,6/5,5/0,0/0
endmode
|
其中最关健是红色那行,分别表示 实际的输出宽度,高度,虚拟输出宽度,高度.和bpp
在描述LCD的物理长度,是指一种对角线物理长度 比如4.3"屏就是对角线为4.3英寸长,这个尺寸与结构设计有关.而与软件编程相关几个参数主要是屏幕分辩率和色深.
屏幕分辩率是指每行和第列的像素数的描述。比如480*272.表示每行分布着480点,每列分布着272点.
每一个像素的颜色是用三原色的分量来表示,即R(red) G (Green) B (blue) 另外一个与软件高度相关是bpp, (bits per pixel),表RGB的bits数。嵌入式LINUX常用 16bpp,18bpp,24bpp. bpp值越大,能表示颜色越丰富.但是占用空间越多.单色的bpp就是1.
一个点占的字节数移为(BPP) bytes per pixel,BPP与bpp的对应换算并不是一个简单除8的关系,要根据硬件换算。一般是16bpp占用2byte,18,24,32均是4个字节.
bpp还一个说法是,色深(Color Deepth)
在lcd的datasheet还是另外一个描述方法,即一个点的最大颜色数,相于是2的bpp次方.因此颜色数是可以直接换算bpp的
- 8bpp的颜色数256
- 16bpp的颜色数 65,536
- 18bpp的颜色数262,144
- 24bpp的颜色数是 16.1m
FB的基本操作
每个fb驱动实际是一个字符设备结点,其主设备号固定为
1。打开FB设备
open("/dev/fb0",O_RDWR,0)
2.控制功能用
3.显存控制
显存是LINUX内核一个空间。应用程序对显存操作是用mmap后来操作
4.关闭设备close()
取得屏幕信息
ioctl(fd, FBIOGET_VSCREENINFO,&var);
取得屏幕信息,数据存放在var中,它是定义在linux/fb.h中struct fb_var_screeninfo当中
struct fb_var_screeninfo { __u32 xres; /* visible resolution */ __u32 yres; __u32 xres_virtual; /* virtual resolution */ __u32 yres_virtual; __u32 xoffset; /* offset from virtual to visible */ __u32 yoffset; /* resolution */
__u32 bits_per_pixel; /* guess what */ __u32 grayscale; /* != 0 Graylevels instead of colors */
struct fb_bitfield red; /* bitfield in fb mem if true color, */ struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; struct fb_bitfield transp; /* transparency */
__u32 nonstd; /* != 0 Non standard pixel format */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */ __u32 width; /* width of picture in mm */
__u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */ __u32 pixclock; /* pixel clock in ps (pico seconds) */ __u32 left_margin; /* time from sync to picture */ __u32 right_margin; /* time from picture to sync */ __u32 upper_margin; /* time from sync to picture */ __u32 lower_margin; __u32 hsync_len; /* length of horizontal sync */ __u32 vsync_len; /* length of vertical sync */ __u32 sync; /* see FB_SYNC_* */ __u32 vmode; /* see FB_VMODE_* */ __u32 rotate; /* angle we rotate counter clockwise */ __u32 reserved[5]; /* Reserved for future compatibility */ };
|
xres /yres 是实际屏幕的分辩率.
xres_virtual/yres_virtual是虚拟屏幕的尺寸
xoffset/yoffset是实际屏幕输出虚拟屏幕.
bits_per_pixel 就是BPP
这一些信息就是
设置屏幕信息
在调整的屏幕信息的作用中,主要切换bpp, 缺省的bpp是由内核配置的.但是在运行中可以切换成不同的bpp.比如一般的s3c6410可以在16bpp/18bpp/24bpp切换.但是每次的切换时只在当前打开的fd有效,关闭后又会变成缺省的bpp.
切换bpp只需要把bits_per_pixel 设为相应的值.
Ioctl(fd, FBIOSET_VSCREENINFO,&var);
var一般是FBIOGET_VSCREENINFO取得缺省值,然后再在其上修改.
在实测时,发现s3c6410的LCD驱动有BUG,即在切换成18bpp时,相应的RGB排列值并未调整,仍然是上一次BPP的排列.这样造成BUG.
解决办法是一是调整LCD驱动,二是在应用程序切换成18bpp时,同时切换成RGB排列.即用如下代码
if(ioctl(fd,FBIOGET_VSCREENINFO,&var)==-1)
{
printf("get screen information failure\n");
return -2;
}
if(bpp == 18)
{
var.red.length = 6;
var.red.offset = 12;
var.red.msb_right = 0;
var.green.length = 6;
var.green.offset = 6;
var.green.msb_right = 0;
var.blue.length = 6;
var.blue.offset = 0;
var.blue.msb_right = 0;
}
var.bits_per_pixel = bpp;
if(ioctl(fd,FBIOPUT_VSCREENINFO,&var)==-1)
{
printf("put screen2 information failure\n");
return -2;
}
|
|
文件: | test_fb.zip |
大小: | 0KB |
下载: | 下载 |
|