上一篇,我们看了Framebuffer驱动的内容,同时framebuffer提供了一些借口,可以让我们比较容易的操作Framebuffer,所以就有了这篇,写一个简单的程序来获取Framebuffer的信息,同时对Framebuffer进行刷写。这个程序适合在Linux系列的系统上测试,例如在Ubuntu 14.04系统上,将代码保存为fb_test.c,然后通过下面的指令编译gcc fb_test.c -o fb_test -std=c99
,alt+ctrl+f1到tty1,然后执行fb_test即可看到效果
测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #include <linux/fb.h> #include <sys/ioctl.h> #include <string.h> #include <sys/mman.h> #define FB0 "/dev/fb0" int main(void) { int fd = 0; char *fd_map = NULL; // 固定参数 struct fb_fix_screeninfo fix_info; // 可变参数 struct fb_var_screeninfo var_info; int ret = -1; memset(&fix_info, 0, sizeof(struct fb_fix_screeninfo)); memset(&var_info, 0, sizeof(struct fb_var_screeninfo)); // 打开framebuffer节点 fd = open(FB0, O_RDWR); if(fd < 0) { char *error_msg = strerror(errno); printf("Open %s failed, errno:%d, error message:%s\n", FB0, errno, error_msg); return -1; } // 通过IOCTL获取可变参数结构体内容 ret = ioctl(fd, FBIOGET_VSCREENINFO, &var_info); if(ret < 0) { char *error_msg = strerror(errno); printf("Get %s var info error, errno:%d, error message:%s\n", FB0, errno, error_msg); return ret; } // 通过IOCTL获取固定参数结构体内容 ret = ioctl(fd, FBIOGET_FSCREENINFO, &fix_info); if(ret < 0) { char *error_msg = strerror(errno); printf("Get %s fix info error, errno:%d, error message:%s\n", FB0, errno, error_msg); return ret; } printf("%s var info, xres=%d, yres=%d\n", FB0, var_info.xres, var_info.yres); printf("%s var info, xres_virtual=%d, yres_virtual=%d\n", FB0, var_info.xres_virtual, var_info.yres_virtual); printf("%s var info, bits_per_pixel=%d\n", FB0, var_info.bits_per_pixel); printf("%s var info, xoffset=%d, yoffset=%d\n", FB0, var_info.xoffset, var_info.yoffset); int screen_size = var_info.xres * var_info.yres * var_info.bits_per_pixel / 8; // 将Framebuffer映射到进程的内存空间 fd_map = (char *)mmap(NULL, screen_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if(fd_map == (char *)-1) { char *error_msg = strerror(errno); printf("Mmap %s failed, errno:%d, error message:%s\n", FB0, errno, error_msg); return -1; } // 将内容写到进程内存空间,Framebuffer驱动会同步刷新到显示屏上 for(unsigned int i = 0; i < var_info.yres / 3; i++) { unsigned int argb = 0; argb = argb | (0xff << 8); for(int j = 0; j < var_info.xres; j++) *((unsigned int *)(fd_map + j * 4 + i * var_info.xres * 4)) = argb; } for(unsigned int i = var_info.yres/3; i < 2 * var_info.yres / 3; i++) { unsigned int argb = 0; argb = argb | (0xff); for(int j = 0; j < var_info.xres; j++) *((unsigned int *)(fd_map + j * 4 + i * var_info.xres * 4)) = argb; } munmap(fd_map, screen_size); close(fd); return 0; } |