简单描述一下framebuffer的使用,它其实就相当于将屏幕上的像素映射到内存中,改变内存中的内容后屏幕自动就变颜色了。

  首先要调用open("/dev/fb0", O_RDWR);打开帧缓冲设备文件,获得文件描述符,然后使用mmap将文件内容映射到内存中,具体映大小取决于屏幕大小,初始化程序如下:

 1 typedef unsigned short color_t;                /* 根据实际情况修改,此处为unsigned short是565的屏 */
 2 
 3 static struct fb_var_screeninfo __g_vinfo;    /* 显示信息 */
 4 static color_t *__gp_frame;                    /* 虚拟屏幕首地址 */
 5 
 6 int framebuffer_init (void)
 7 {
 8     int fd = 0;
 9 
10     fd = open("/dev/fb0", O_RDWR);
11     if (fd == -1) {
12         perror("fail to open /dev/fb0\n");
13         return -1;
14     }
15 
16     ioctl(fd, FBIOGET_VSCREENINFO, &__g_vinfo);                    /* 获取显示信息 */
17     printf("bits_per_pixel = %d\n", __g_vinfo.bits_per_pixel);    /* 得到一个像素点对应的位数 */
18 
19     __gp_frame = mmap(NULL,                             /* 映射区的开始地址,为NULL表示由系统决定映射区的起始地址 */
20                       __g_vinfo.xres_virtual * __g_vinfo.yres_virtual * __g_vinfo.bits_per_pixel / 8,    /* 映射区大小 */
21                       PROT_WRITE | PROT_READ,            /* 内存保护标志(可读可写) */
22                       MAP_SHARED,                        /* 映射对象类型(与其他进程共享) */
23                       fd,                                /* 有效的文件描述符 */
24                       0);                                /* 被映射内容的偏移量 */
25     if (__gp_frame == NULL) {
26         perror("fail to mmap\n");
27         return -1;
28     }
29 
30     return 0;
31 }

初始化成功后对__gp_frame指针操作就相当于对屏幕进行操作了。附上完整测试程序:

 1 /**
 2  * filename: framebuffer.c
 3  * author: Suzkfly
 4  * date: 2021-07-28
 5  * platform: S3C6410或Ubuntu
 6  * 编译程序并运行,屏幕上间隔1s显示红绿蓝三种不同颜色。
 7  */
 8  
 9 #include <stdio.h>
10 #include <linux/fb.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <sys/mman.h>
15 
16 /**< \brief 根据实际情况修改,此处为unsigned short是565的屏,根据程序打印出的
17     bits_per_pixel的值可以判断出输出格式是565还是888 */
18 typedef unsigned short color_t;    /* 565的屏 */          
19 #define BLUE    0x001F  /* 蓝色 */
20 #define GREEN   0x07E0  /* 绿色 */
21 #define RED     0xF800  /* 红色 */
22 //typedef unsigned int color_t;    /* 888的屏 */          
23 //#define BLUE   0x000000FF  /* 蓝色 */
24 //#define GREEN  0x0000FF00  /* 绿色 */
25 //#define RED    0x00FF0000  /* 红色 */
26 
27     
28 static struct fb_var_screeninfo __g_vinfo;    /* 显示信息 */
29 static color_t *__gp_frame;                   /* 虚拟屏幕首地址 */
30 
31 int framebuffer_init (void)
32 {
33     int fd = 0;
34 
35     fd = open("/dev/fb0", O_RDWR);
36     if (fd == -1) {
37         perror("fail to open /dev/fb0\n");
38         return -1;
39     }
40 
41     ioctl(fd, FBIOGET_VSCREENINFO, &__g_vinfo);                   /* 获取显示信息 */
42     printf("bits_per_pixel = %d\n", __g_vinfo.bits_per_pixel);    /* 一个像素点对应的位数,如果值为16则为565格式输出,如果值为32则为888格式输出 */
43     printf("xres_virtual = %d\n", __g_vinfo.xres_virtual);        /* 虚拟x轴像素点数 */
44     printf("yres_virtual = %d\n", __g_vinfo.yres_virtual);        /* 虚拟y轴像素点数 */
45     printf("xres = %d\n", __g_vinfo.xres);                        /* x轴像素点数 */
46     printf("yres = %d\n", __g_vinfo.yres);                        /* y轴像素点数 */
47 
48     __gp_frame = mmap(NULL,                              /* 映射区的开始地址,为NULL表示由系统决定映射区的起始地址 */
49                       __g_vinfo.xres_virtual * __g_vinfo.yres_virtual * __g_vinfo.bits_per_pixel / 8,    /* 映射区大小 */
50                       PROT_WRITE | PROT_READ,            /* 内存保护标志(可读可写) */
51                       MAP_SHARED,                        /* 映射对象类型(与其他进程共享) */
52                       fd,                                /* 有效的文件描述符 */
53                       0);                                /* 被映射内容的偏移量 */
54     if (__gp_frame == NULL) {
55         perror("fail to mmap\n");
56         return -1;
57     }
58 
59     return 0;
60 }
61 
62 /**
63  * \brief 填充整屏
64  */
65 void full_screen (color_t color)
66 {
67     int i;
68     color_t *p = __gp_frame;
69 
70     for (i = 0; i < __g_vinfo.xres_virtual * __g_vinfo.yres_virtual; i++) {
71         *p++ = color;
72     }
73 }
74 
75 int main(int argc, const char *argv[])
76 {
77     if (framebuffer_init()) {
78         printf("framebuffer_init failed\n");
79         return 0;
80     }
81 
82     while (1) {
83         full_screen(RED);       /* 填充红色 */
84         sleep(1);
85         full_screen(GREEN);     /* 填充绿色 */
86         sleep(1);
87         full_screen(BLUE);      /* 填充蓝色 */
88         sleep(1);
89     }
90 
91     return 0;
92 }

 

执行程序后屏幕交替显示红绿蓝三种颜色。