Linux 下 FrameBuffer 的使用
Linux 下 FrameBuffer 的使用

Linux 下 FrameBuffer 的使用

用一个实例说明 Linux 下 FrameBuffer 的使用

X-Window-System 是 Unix/Linux 上的图形系统,它是通过 X-Server 来控制硬件的。FrameBuffer 不是一个图形系统,更不是窗口系统。它比 X 要低级,简单来说 FrameBuffer就 是一种机制的实现。这种机制是把屏幕上的每个点映射成一段线性内存空间,程序可以简单的改变这段内存的值来改变屏幕上某一点的颜色。X 的高度可移植性就是来自于这种机制,不管是在那种图形环境下,只要有这种机制的实现就可以运行 X。所以在几乎所有的平台上都有相应的 X 版本的移植。

FrameBuffer 对应的驱动为 /dev/fb*。

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main () {
  int fp=0;
  struct fb_var_screeninfo vinfo;
  struct fb_fix_screeninfo finfo;
  long screensize=0;
  char *fbp = 0;
  int x = 0, y = 0;
  long location = 0;

  //以可读可写的形式打开 "/dev/fb0" 文件
 fp = open ("/dev/fb0",O_RDWR);

  //打开失败
  if (fp < 0){
    printf("Error : Can not open framebuffer device/n");
    exit(1);
  }

  //获取 fb_var_screeninfo 参数信息
  //成员变量 smem_len 是这个 /dev/fb0 的大小,也就是内存大小
  //成员变量 line_length 是屏幕上一行的点在内存中占有的空间,不是一行上的点数
  if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
    printf("Error reading fixed information/n");
    exit(2);
   }
 
  //获取 fb_fix_screeninfo 参数信息
  //成员变量 xres、yres 是 x 和 y 方向的分辨率,就是两个方向上的点数
  //成员变量 bits_per_pixel 是每一点占有的内存空间,32 表示一个像素点大小为 32 位。
  if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
    printf("Error reading variable information/n");
    exit(3);
  }

  //计算屏幕占据的内存大小(字节)
  screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

  //把 fp 所指的文件中从开始到 screensize 大小的内容给映射出来,得到一个指向这块空间的指针
  fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
  if ((int) fbp == -1)
  {
    printf ("Error: failed to map framebuffer device to memory./n");
    exit (4);
  }
  
  //设置坐标,(0,0)点在屏幕左上角,并计算坐标对应的内存地址
  x = 100;
  y = 100;
  location = x * (vinfo.bits_per_pixel / 8) + y  *  finfo.line_length;

  //画点,按照 ARGB8888 格式,直接赋值来改变屏幕上某点的颜色
  *(fbp + location)     = 100; //蓝色的色深
  *(fbp + location + 1) = 15;  //绿色的色深
  *(fbp + location + 2) = 200; //红色的色深
  *(fbp + location + 3) = 0;   //透明度
  
  解除映射
  munmap (fbp, screensize);

  关闭文件
  close (fp);

  //返回
  return 0;
}