(frame buffer -> fb0)屏幕设备内存映射操作(1)

    xiaoxiao2025-09-19  17

    /**  * @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; } 结果:

    红色部分 划出的一条线
    转载请注明原文地址: https://ju.6miu.com/read-1302808.html
    最新回复(0)