/** * @file demo1.c * @Synopsis /dev/fb0 屏幕设备内存映射操作 * 1:当在ubuntu 下可能有的不存在此设备,需要进行相关参数配制。这里就不作详解了。 * 2:不过在打开此设备情况下,需要对该设备文件 * 进行权限设置sudo chmod 777 /dev/fb0 * 3:运行此程序时如果开启了图形界面功能,则需切换终端 * CTRL+ALT+F1 切换终端 * ALT+F7 切回图形界面 * 当然如果是糸统默认加载是非图形界面,这里就不需要切换了。 * * @author MrClimb * @version 1.1.0 * @date 2012-05-10 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/ioctl.h> #include <sys/mman.h> /** * 定义一个结构体 */ typedef struct { int w; int h; int bpp; void *memo;// 存内存范型首地址 } fbscr_t; fbscr_t fb_v; void init_data(void) { /** * 打开屏幕设备 */ int fd = open("/dev/fb0", O_RDWR); if(fd < 0) { perror("fb0"); exit(1); } struct fb_var_screeninfo fb_var;//定义设备屏幕信息 /** * int ioctl(int d, int request, ...); * function:用来控制设备文件的属性 * @param int d 文件描述符 这里相当于把这个设备传给了ioctl * @param int request * @param ... 一般为 char *argp * 它随第二个参数 request 不同而不同,参数request 决定了argp是向ioctl 传数据,还是从ioctl 取数据 * @return -1 出错 0 成功
* FBIOGET_VSCREENINFO 对屏幕控制 * file byte io get v screen info * 获得该屏幕设备信息放组装到 fb_var 中结构体中 * */ if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) < 0) { perror("ioctl"); exit(1); }
printf("屏幕的宽度:%d\n",fb_var.xres); printf("屏幕的高度:%d\n",fb_var.yres); printf("每像素比特位数:%d\n",fb_var.bits_per_pixel); fb_v.w = fb_var.xres;// 设置屏幕宽度 fb_v.h = fb_var.yres;// 设置屏幕高度 fb_v.bpp = fb_var.bits_per_pixel;// 设置每像素比特位数值
printf("width: %d\n",fb_v.w); printf("height:%d\n",fb_v.h); printf("bpp:%d\n",fb_v.bpp); /** * void * mmap(void*addr,size_t length,int prot,int flags,int fd,off_t offset); * 划分屏幕内存映射 * @param void *addr 指向内存的地址,这里由糸统自定义分配 * @param size_t length 在内存区域划分的长度,这里以屏幕来进行计算值 * (屏宽* 屏高 * 每像素比特位数)/8 = ?字节数 * 每像素比特位数这里在 32位操作糸统下 为32 * 一个字节占8位,这里所以除8啦 * @param prot PROT_READ|PROT_WRITE 对映射的这块数据执行读与定权限 * @param flags MAP_SHARED 线程共享的 * @param int fd 文件描述符 * @param off_t offset 从0 位置偏移映射 * @return MAP_FAILED | void * 有效地址 */ fb_v.memo = mmap(NULL, fb_v.w*fb_v.h*fb_v.bpp/8, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); /** * MAP_FAILED 映射失败 */ if(fb_v.memo == MAP_FAILED) { perror("map"); exit(1); } /** * 反回无符号 整型地址,也就是内存映射屏幕 整型指针首地址 */ unsigned int *p = fb_v.memo; /** * p+1024*100+512 */ int i = 0; for(i = 0; i<100; i++) { //*(p+i) = 0x00ff0000;// 32 位 结果发现画出了一条红线 /** * 我想换一行划出横线 */ // *(p+1024+i) = 0x00ff0000;// 结果没看出效果 /** * 下面移位50行划出一行线 */ // *(p+1024*50+i) = 0x00ff0000;
/** * 向右移,移到差不多中间去 */ *(p+1024*100+512+i) = 0x00ff0000; } close(fd); } int main(void) { init_data(); return 0; } 结果:
红色部分 划出的一条线