免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2194 | 回复: 1
打印 上一主题 下一主题

[Linux] 访问Frame Buffer,为何导致"Segment fault"错误? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-02-05 22:10 |只看该作者 |倒序浏览
下面的程序用于在屏幕上绘制一个矩形,在Ubuntu中能够编译通过,但运行时提示“Segmentation fault”。用GDB跟踪发现在第54行发生错误。既然已经将Frame Buffer映射到了进程地址空间中,为何不能访问该内存呢?

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

int main()
{
  int fbfd = 0;
  struct fb_var_screeninfo vinfo;
  struct fb_fix_screeninfo finfo;
  struct fb_cmap cmapinfo;
  long int screensize = 0;
  char *fbp = 0;
  int x = 0, y = 0;
  long int location = 0;
  int b, g, r;
  
  fbfd = open("/dev/fb0", O_RDWR);
  if (fbfd < 0){
    printf("Error: can not open framebuffer device: %x\n", fbfd);
    exit(1);
  }
  printf("The framebuffer device was opened successfully.\n");
  if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)){
    printf("Error reading fixed information.\n");
    exit(2);
  }
  printf("%s\n", finfo.id);
  printf("type: 0x%x\n", finfo.type);
  printf("visual: %d\n", finfo.visual);
  printf("line_length: %d\n", finfo.line_length);
  printf("mem_start: 0x%lx, smem_len: %d\n", finfo.smem_start, finfo.smem_len);
  printf("mmio_start: 0x%lx, mmio_len: %d\n", finfo.mmio_start, finfo.mmio_len);

  if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)){
    printf("Error reading variable information. \n");
    exit(3);
  }
  printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
  screensize = vinfo.xres * vinfo.bits_per_pixel / 8;
  fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  if ((int)fbp == -1){
    printf("Error: failed to map framebuffer device to memory.\n");
    exit(4);
  }
  printf("The framebuffer device was mapped to memory successfully.\n");
  vinfo.xoffset = (vinfo.xres - 420) / 2;
  vinfo.yoffset = (vinfo.yres - 340) / 2;
  b = 10; g = 100; r = 100;
  for (y = 0; y < 340; y++)
    for ( x = 0; x < 420; x++){
      location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8 <<===== 这里发生错误
        + (y + vinfo.yoffset) * finfo.line_length;
      if (vinfo.bits_per_pixel == 32){
        *(fbp + location) = b;
        *(fbp + location + 1) = g;
        *(fbp + location + 2) = r;
        *(fbp + location + 3) = 0;
      }
      else{
        unsigned short int t = r << 11 | g << 5 | b;
        *((unsigned short int *)(fbp + location)) = t;
      }
    }
  munmap(fbp, screensize);
  close(fbfd);
  return 0;
}

论坛徽章:
0
2 [报告]
发表于 2013-02-06 16:44 |只看该作者
哥们,这行肯定不会有蛋错误
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP