Framebuffer 显示不全

T帮主 2017-06-06 11:46:26
目前在测试Framebuffer 。在网上找的绘制矩形的程序, 我的板子默认是1024*600的分辨率。通过fbset设置分辨率为1920*1080.

目前会出现垂直刷数据的时候 刷到1013就会出现 Segmentation fault。并且1013之后的数据就无法显示。


有遇到这种情况的没
...全文
328 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
jklinux 2017-06-07
  • 打赏
  • 举报
回复
建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
T帮主 2017-06-07
  • 打赏
  • 举报
回复
开发环境 arm Linux
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 8 楼 jklinux 的回复:
[quote=引用 6 楼 keleming1 的回复:] [quote=引用 2 楼 jklinux 的回复:] 建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
现在的问题 好像 也比较明显了。 mmap的时候 ,其中fr_dev->screensize计算出来的大小为 screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; =1920*1080*4=8294400 fr_dev->map_fb=(char *)mmap(NULL,fr_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0); 而填充rgb数据的时候,写到第1013行的时候location的大小为line_length*1013=8192*1013=8298496。这个大小大于screensize 8294400,这个时候 就出现了段错误。所以现在考虑是不是 line_length的大小有问题,但是这个属于帧缓存的固定参数,目前没法通过ioctl修改。 location=(x+fr_dev->vinfo.xoffset)*(fr_dev->vinfo.bits_per_pixel/8)+(y+fr_dev->vinfo.yoffset)*fr_dev->finfo.line_length; *(fr_dev->map_fb+location)=b1; *(fr_dev->map_fb+location+1)=g1; *(fr_dev->map_fb+location+2)=r1; *(fr_dev->map_fb+location+3)=a1; 不知道分析的对不对,如果是这样,要修改驱动吗? 有没有其他的方法。谢谢各位了[/quote] 这个line_length是很重要的,用line_length/4作一行的像素个数试下. 另:嵌入式里的lcd一般都是分辨率固定的,为什么要改呢?[/quote] 问题解决了 谢谢jklinux 解决方法:修改mmap时 screensize的大小。 修改为1080*8192. fr_dev->map_fb=(char *)mmap(NULL,1080*2048*4,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0);
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 8 楼 jklinux 的回复:
[quote=引用 6 楼 keleming1 的回复:] [quote=引用 2 楼 jklinux 的回复:] 建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
现在的问题 好像 也比较明显了。 mmap的时候 ,其中fr_dev->screensize计算出来的大小为 screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; =1920*1080*4=8294400 fr_dev->map_fb=(char *)mmap(NULL,fr_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0); 而填充rgb数据的时候,写到第1013行的时候location的大小为line_length*1013=8192*1013=8298496。这个大小大于screensize 8294400,这个时候 就出现了段错误。所以现在考虑是不是 line_length的大小有问题,但是这个属于帧缓存的固定参数,目前没法通过ioctl修改。 location=(x+fr_dev->vinfo.xoffset)*(fr_dev->vinfo.bits_per_pixel/8)+(y+fr_dev->vinfo.yoffset)*fr_dev->finfo.line_length; *(fr_dev->map_fb+location)=b1; *(fr_dev->map_fb+location+1)=g1; *(fr_dev->map_fb+location+2)=r1; *(fr_dev->map_fb+location+3)=a1; 不知道分析的对不对,如果是这样,要修改驱动吗? 有没有其他的方法。谢谢各位了[/quote] 这个line_length是很重要的,用line_length/4作一行的像素个数试下. 另:嵌入式里的lcd一般都是分辨率固定的,为什么要改呢?[/quote] 我这个项目 没有用lcd 图像数据最终要通过cvbs传到其他的中控监视平台上去 所以彩调整了分辨率 谢谢jklinux的回复 很有启发 我试试看
jklinux 2017-06-07
  • 打赏
  • 举报
回复
引用 6 楼 keleming1 的回复:
[quote=引用 2 楼 jklinux 的回复:] 建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
现在的问题 好像 也比较明显了。 mmap的时候 ,其中fr_dev->screensize计算出来的大小为 screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; =1920*1080*4=8294400 fr_dev->map_fb=(char *)mmap(NULL,fr_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0); 而填充rgb数据的时候,写到第1013行的时候location的大小为line_length*1013=8192*1013=8298496。这个大小大于screensize 8294400,这个时候 就出现了段错误。所以现在考虑是不是 line_length的大小有问题,但是这个属于帧缓存的固定参数,目前没法通过ioctl修改。 location=(x+fr_dev->vinfo.xoffset)*(fr_dev->vinfo.bits_per_pixel/8)+(y+fr_dev->vinfo.yoffset)*fr_dev->finfo.line_length; *(fr_dev->map_fb+location)=b1; *(fr_dev->map_fb+location+1)=g1; *(fr_dev->map_fb+location+2)=r1; *(fr_dev->map_fb+location+3)=a1; 不知道分析的对不对,如果是这样,要修改驱动吗? 有没有其他的方法。谢谢各位了[/quote] 这个line_length是很重要的,用line_length/4作一行的像素个数试下. 另:嵌入式里的lcd一般都是分辨率固定的,为什么要改呢?
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 2 楼 jklinux 的回复:
建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
现在我有个疑惑 跟用哪个程序没关系 就是line_length = 8192 Framebuffer的每行字节数line_length 是8192个字节 这个是帧缓存的固定参数决定的 也就是说驱动里面写死的 然后我要显示的分辨率是1920*1080 也就是要显示1080行 这样算下来显存大小至少应该是 1080*8192 = 8847360 而通过fbset查询到的 或者通过ioctl查询到的显存大小确实是 8847360 但通过mmap 映射显存的时候,screensize的计算方法却是1920*1080*(32/8)=8294400 但是这个小于显存大小 1080*8192 = 8847360 mmap(NULL,fr_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0); 因此导致 后面写grb数据的时候 写到1013行的时候 计算出来的位置大于screensize的大小 出现段错误。 这个要怎么解啊
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 2 楼 jklinux 的回复:
建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
现在的问题 好像 也比较明显了。 mmap的时候 ,其中fr_dev->screensize计算出来的大小为 screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; =1920*1080*4=8294400 fr_dev->map_fb=(char *)mmap(NULL,fr_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fr_dev->fdfd,0); 而填充rgb数据的时候,写到第1013行的时候location的大小为line_length*1013=8192*1013=8298496。这个大小大于screensize 8294400,这个时候 就出现了段错误。所以现在考虑是不是 line_length的大小有问题,但是这个属于帧缓存的固定参数,目前没法通过ioctl修改。 location=(x+fr_dev->vinfo.xoffset)*(fr_dev->vinfo.bits_per_pixel/8)+(y+fr_dev->vinfo.yoffset)*fr_dev->finfo.line_length; *(fr_dev->map_fb+location)=b1; *(fr_dev->map_fb+location+1)=g1; *(fr_dev->map_fb+location+2)=r1; *(fr_dev->map_fb+location+3)=a1; 不知道分析的对不对,如果是这样,要修改驱动吗? 有没有其他的方法。谢谢各位了
jklinux 2017-06-07
  • 打赏
  • 举报
回复
引用 4 楼 keleming1 的回复:
[quote=引用 2 楼 jklinux 的回复:] 建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
加了些打印信息 发现 下面没有显示的地方 出现了段错误 并且这个时候 location的位置信息 大于screensize: 8294400长度。其中smem_len为screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; >>>location: 8290336 >>> location: 8290340 >>>location: 8298496 1920*1080*4=8294400 Segmentation fault[/quote] 建议楼主自己写下代码来刷下颜色试下,别人的程序有bug也是有可能的
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 2 楼 jklinux 的回复:
建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
加了些打印信息 发现 下面没有显示的地方 出现了段错误 并且这个时候 location的位置信息 大于screensize: 8294400长度。其中smem_len为screensize=vinfo.xres*yres*vinfo.bits_per_pixel/8; >>>location: 8290336 >>> location: 8290340 >>>location: 8298496 1920*1080*4=8294400 Segmentation fault
T帮主 2017-06-07
  • 打赏
  • 举报
回复
引用 2 楼 jklinux 的回复:
建议楼主先通过ioctl获取出分辨率,确定分辨率具体是多少值。并不是说你设了就得支持的。 struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); x = vinfo.xres; y = vinfo.yres; ///////////////////////////////////如果花屏还得做下面这步/////////// struct fb_fix_screeninfo finfo; ioctl(fd, FBIOGET_FSCREENINFO, &finfo); len_line = finfo.line_length; // 一行多少个像素还得用"len_lien/位色/8"算出才是真正的。里面驱动按一定的规则对齐的
谢谢的回复jklinux 目前从通过ioctl获得的信息来看 分辨率是对的。 the framebuffer device was opended successfully. id omapdrm smem_start 2138636288 smem_len 8847360 type 0 type_aux 0 visual 2 xpanstep 1 ypanstep 1 line_length 8192 mmio_start 0 mmio_len 0 accel 0 xres 1920 yres 1080 xres_virturl 1920 yres_virtual 1080 xoffset 0 yoffset 0 bits_per_pixel 32 grayscale 0 fb_bitfield red.offset 16 fb_bitfield .length 8 fb_bitfield .msb_right 0 fb_bitfield green.offset 8 fb_bitfield .length 8 fb_bitfield .msb_right 0 fb_bitfield blue.offset 0 fb_bitfield .length 8 fb_bitfield .msb_right 0 fb_bitfield transp.offset 24 fb_bitfield .length 8 fb_bitfield .msb_right 0 nonstd 0 activate 0 height 0 widht 0 accel_flags 1 >>>init_dev xres: 1920 yres: 1080 bits_per_pixel: 32 >>>init_dev screensize: 8294400 下面是 写rgb数据的 部分代码。显示出来的颜色 目前来看都是对的。 location=(x+fr_dev->vinfo.xoffset)*(fr_dev->vinfo.bits_per_pixel/8)+(y+fr_dev->vinfo.yoffset)*fr_dev->finfo.line_length; *(fr_dev->map_fb+location)=b1; *(fr_dev->map_fb+location+1)=g1; *(fr_dev->map_fb+location+2)=r1; *(fr_dev->map_fb+location+3)=a1; 其中fr_dev->vinfo.xoffse =0;fr_dev->vinfo.yoffset=0;fr_dev->vinfo.bits_per_pixel=32;fr_dev->finfo.line_length = 8192。 并且fbset -i 信息如下 mode "1920x1080" geometry 1920 1080 1920 1080 32 timings 0 0 0 0 0 0 0 accel true rgba 8/16,8/8,8/0,8/24 endmode Frame buffer device information: Name : omapdrm Address : 0x7f790000 Size : 8847360 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 1 YPanStep : 1 YWrapStep : 1 LineLength : 8192 Accelerator : No

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧