亲自动手编程 framebuffer.

来源:互联网 发布:js时间插件 编辑:程序博客网 时间:2024/06/06 18:24
在网上找了很多关于framebuffer的资料,不过都只属于理论的学习,今天亲自动手对我的pxa270平台进行编程framebuffer.把自己总结的步骤共享给大家。
1. 了解linux/fb.h中的关于framebuffer的结构体 fb_fix_screeninfo和fb_var_screeninfo中的内容。(红色的是我用到的内容,也是编程经常要用到的)。
   struct fb_fix_screeninfo {   //存放于设备无关的常值信息,如显存大小等。
  char id[16];   /* identification string eg "TT Builtin" */
     unsigned long smem_start; /* Start of frame buffer mem 显存起始地址*/
      /* (physical address) */
    __u32 smem_len;   /* Length of frame buffer mem 显存大小*/
    __u32 type;   /* see FB_TYPE_*  */
    __u32 type_aux;   /* Interleave for interleaved Planes */
    __u32 visual;   /* see FB_VISUAL_*  */
    __u16 xpanstep;   /* zero if no hardware panning  */
    __u16 ypanstep;   /* zero if no hardware panning  */
    __u16 ywrapstep;  /* zero if no hardware ywrap    */
    __u32 line_length;  /* length of a line in bytes  每一行字节数  */
    unsigned long mmio_start; /* Start of Memory Mapped I/O   */
     /* (physical address) */
    __u32 mmio_len;   /* Length of Memory Mapped I/O  */
    __u32 accel;   /* Indicate to driver which */
     /*  specific chip/card we have */
   __u16 reserved[3];  /* Reserved for future compatibility */
};
 
 
 
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 * bits_per_pixel/8  (BYTES)
 
2.编程流程:
  (1) 打开设备 open("/dev/fb0",O_RDWR);
  (2)  获取framebuffer设备信息.ioctl(int fb,FBIOGET_FSCREENINFO,&finfo);
       ioctl函数是实现对设备的信息获取和设定,第一个参数为文件描述符,第二个参数为具体设备的参数,对于framebuffer,参数在linux/fb.h中定义的。
      #define FBIOGET_VSCREENINFO 0x4600   //获取设备无关的数据信息fb_var_screeninfo
      #define FBIOPUT_VSCREENINFO 0x4601   //设定设备无关的数据信息
      #define FBIOGET_FSCREENINFO 0x4602   //获取设备无关的常值信息fb_fix_screeninfo
      #define FBIOGETCMAP  0x4604        //获取设备无关颜色表信息
      #define FBIOPUTCMAP  0x4605       //设定设备无关颜色表信息
      #define FBIOPAN_DISPLAY  0x4606
      #define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor)
      第三个参数是存放信息的结构体或者缓冲区
 (3)内存映射 mmap函数。头文件:sys/mman.h .常用用法:mmap(0,screensize,PROT_RD |PROT_WR,MAP_SHARED,int fb,0)返回映射的首地址。
 
3。实例
程序实现在lcd 上全屏写 blue 色
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
int main()
{
        int fbfd = 0;
        struct fb_var_screeninfo vinfo;
        struct fb_fix_screeninfo finfo;
        long int screensize = 0;
        char *fbp = 0;
        int x = 0, y = 0;
        long int location = 0;
       int sav=0;
 
        /* open device*/
        fbfd = open("/dev/fb0", O_RDWR);
        if (!fbfd) {
                printf("Error: cannot open framebuffer device.\n");
                exit(1);
        }
        printf("The framebuffer device was opened successfully.\n");
       
        /* Get fixed screen information */
        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
                printf("Error reading fixed information.\n");
                exit(2);
        }
 
        /* Get variable screen information */
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
                printf("Error reading variable information.\n");
                exit(3);
        }
/* show these information*/
 printf("vinfo.xres=%d\n",vinfo.xres);
 printf("vinfo.yres=%d\n",vinfo.yres);
 printf("vinfo.bits_per_bits=%d\n",vinfo.bits_per_pixel);
 printf("vinfo.xoffset=%d\n",vinfo.xoffset);
 printf("vinfo.yoffset=%d\n",vinfo.yoffset);
 printf("finfo.line_length=%d\n",finfo.line_length);

        /* Figure out the size of the screen in bytes */
        screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
       
        /* Map the device to memory */
        fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                fbfd, 0);      
        if ((int)fbp == -1) { printf("Error: failed to map framebuffer device to memory.\n"); exit(4);
        }
        printf("The framebuffer device was mapped to memory successfully.\n");
 memset(fbp,0,screensize);
            /* Where we are going to put the pixel */
 
 for(x=0;x<vinfo.xres;x++)
 for(y=0;y<vinfo.yres;y++)
 {
 
 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
         (y+vinfo.yoffset) * finfo.line_length;
        *(fbp + location) = 0xff; /*  blue */
        *(fbp + location + 1) = 0x00;     
         }            
      munmap(fbp, screensize);  /* release the memory */
      close(fbfd); 
      return 0;
}
这是最简单的直接写framebuffer 的程序,也是我在这一方面编程的起步。希望在以后的学习中能够和朋友们一起提高。
     
 
 
 
 
 
 
 
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1884) | 评论(0) | 转发(0) |
0

上一篇:VMware 修改linux 分辨率(fc8)

下一篇:显示设置vga framebuffer

相关热门文章
  • linux 常见服务端口
  • xmanager 2.0 for linux配置
  • 【ROOTFS搭建】busybox的httpd...
  • openwrt中luci学习笔记
  • 什么是shell
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
原创粉丝点击