您的位置:首页 > 运维架构 > Linux

Linux frame buffer 编程 -- fb基本操作

2012-10-15 10:23 471 查看
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.1mFB的基本操作
每个fb驱动实际是一个字符设备结点,其主设备号固定为1。打开FB设备
open("/dev/fb0",O_RDWR,0)
2.控制功能用ioctl实现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; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: