Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22764
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-29 19:57
文章分类
文章存档

2014年(13)

2013年(6)

我的朋友

分类: 嵌入式

2014-02-08 10:57:38

Andrew Huang 转载请注明作者及网址

 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.控制功能用
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;
       }

文件:test_fb.zip
大小:0KB
下载:下载
阅读(298) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~