Linux FrameBuffer(二)- VMware虚拟机的Ubuntu系统FrameBuffer画图

简介: Linux FrameBuffer(二)- VMware虚拟机的Ubuntu系统FrameBuffer画图

一、确认/dev/fb0文件存在

在Ubuntu上画图,需要对应的FrameBuffer设备文件的支持,一般FrameBuffer的设备文件路径为/dev/fb开头的,可能是/dev/fb0或/dev/fb1等,所以进行下面的步骤之前要先确保/dev/fb*的文件是否存在。

如果你的Ubuntu版本比较旧,没有/dev/fb0的设备文件的话,可以参照这个文章:虚拟机的 Ubuntu 没有 /dev/fb0 的解决办法


二、Ubuntu进入命令行模式

Ubuntu有命令行模式和图形界面模式l,在图形界面模式时,即使执行了在/dev/fb0画图的程序也无法看到效果,所以执行FrameBuffer画图程序时,需要进入命令行。

可以通过按快捷键 Ctrl + Alt + F1来切换到命令行模式,通过按Ctrl + Alt + F7切换到图形界面模式。切换到命令行模式也可以Ctrl + Alt + (F1~F6任意一个)去切换。


三、在命令行模式下,执行FrameBuffer画图程序。

如果你自己有已经写好的FrameBuffer程序,经过前面两个步骤,应该可以执行跑起来了看到画图的效果了。运行程序时,需要加sudo,不然没有权限打开设备文件。如果没有程序或者跑起来有问题,可以复制下面代码编译执行,执行结果就是在左上角画一个30*30的方块,每秒变一个颜色,如图:2018122814580746.png

// framebuffer.c
#include <stdio.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
unsigned int fb_byteW=0, fb_byteH=0; // 用字节表示的宽度和高度
unsigned int bytesPerPixel = 0; // 一个像素占用的字节数
char *fbMapMem = NULL;
void fillRect(int color, int x, int y, int w, int h)
{
  int i=0, j=0, offset = 0;
  if(bytesPerPixel==4)
  {
    for(i=0; i<h; i++)
    {
      offset = x*bytesPerPixel + (y+i)*fb_byteW;
      for(j=0; j<w; j++)
      {
        int *tmp = (int *)&fbMapMem[offset];
        *tmp = color;
        offset += bytesPerPixel;
      }
    }
  }
  else
    printf("error bytesPerPixel=%d\n", bytesPerPixel);
}
int main(int argc, char *argv[])
{
  // 1.打开设备
  char fbPath[64] = "/dev/fb0";
  int framebuf_fd = open(fbPath, O_RDWR);
  if ( framebuf_fd < 0 ) {
        printf("[%s:%d] open %s error \n", __FILE__,__LINE__,fbPath);
        return -1;
    }
  // 2.获取设备固定参数
  struct fb_fix_screeninfo finfo;
  if (ioctl(framebuf_fd, FBIOGET_FSCREENINFO, &finfo) < 0)
    {
        fprintf(stderr, "ioctl FBIOGET_FSCREENINFO err \r\n");
        return -1;
    }
  // 3.1 获取虚拟参数
  struct fb_var_screeninfo vinfo;
    if (ioctl(framebuf_fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
    {
        fprintf(stderr, "ioctl FBIOGET_VSCREENINFO err \r\n");
        return -1;
    }
  // 3.2 设置虚拟参数
  bytesPerPixel = vinfo.bits_per_pixel / 8;
  vinfo.xres = vinfo.xres_virtual = finfo.line_length/bytesPerPixel;
  if (ioctl(framebuf_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0)
    {
        fprintf(stderr, "ioctl FBIOPUT_VSCREENINFO err \r\n");
        return -1;
    }
  fb_byteW = vinfo.xres * bytesPerPixel;
  fb_byteH = vinfo.yres * bytesPerPixel;
  printf("[line:%d] line_length=%d res=[%dx%d], Bpp=%d ByteWH=[%d %d]\n",__LINE__,finfo.line_length,vinfo.xres,vinfo.yres,bytesPerPixel,fb_byteW, fb_byteH);
  // 4.映射物理显存到用户虚拟内存空间
  unsigned long size = vinfo.xres*vinfo.yres*bytesPerPixel;
    if (NULL == (fbMapMem=(char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, framebuf_fd, 0)) )
    {
        fprintf(stderr, "mmap size %ld err \r\n", size);
        return -1;
    }
  // 5.操作虚拟内存,完成具体绘制任务,每隔一秒画一个颜色的正方形
  while(1)
  {
    fillRect(0xff0000,0,0,30,30);// 红色
    sleep(1);
    fillRect(0x00ff00,0,0,30,30);// 绿色
    sleep(1);
    fillRect(0x0000ff,0,0,30,30);// 蓝色
    sleep(1);
  }
  // 6.解除显存映射
  munmap(fbMapMem, size);
  // 7.关闭设备
  close(framebuf_fd);
  return 0;
}

四、虚拟机Ubuntu的FrameBuffer(/dev/fb0)画图的问题

如果你执行画图程序后,能出来东西,但画出来的图不是自己想要的,感觉分辨率没对应上,像下图一样。

2018122814580746.png

原因可能就是设备固定参数(struct fb_fix_screeninfo)的line_length字段字节数,跟虚拟参数(struct fb_var_screeninfo)的分辨率的宽xres字段对不上。需要在你的程序里添加这句代码,再设置虚拟参数,可以参考上面代码。

vinfo.xres = vinfo.xres_virtual = finfo.line_length/bytesPerPixel;


目录
相关文章
|
6月前
|
Ubuntu Linux UED
Ubuntu和Debian系统与Hat Linux系列的使用比较
所以,如果你想搞一个家用服务器,或者是个人使用,喜欢新鲜事物,那Ubuntu可能是你的最好选择。如果你需要一个在商业环境中经受住考验的系统,那Fedora或CentOS可能更符合你的口味。不过记住,CentOS现在是CentOS Stream,中途换马了,所以如果你是稳定性的极端追求者,可能得考虑一下这一变化。而Debian,则适合那些对稳定性需求极高,不太追求软件版本新旧的用户。
209 26
|
6月前
|
Ubuntu 搜索推荐 Linux
Ubuntu/Debian Hat系Linux的便捷操作指南
总的来说,虽然Ubuntu/Debian和Red Hat系列在操作方法上有所不同,但基本概念类似。掌握了包管理和服务管理,可以应对大多数常见的系统管理任务。同时,这两个系统都有丰富的在线资源可以查询,不管你在任务中遇到什么困难,搜索引擎都能帮你找到答案。这些基本技能能让你在Linux的世界里更加自如。
206 26
|
6月前
|
Ubuntu Linux Shell
Linux环境下VSCode快速安装终极指南:debian/ubuntu/linux平台通用
以上就是在Linux环境下安装VSCode的终极指南,抛开繁复的专业词汇,以平易近人的文字、形象生动的比喻让你轻松学会这一过程。别忘了,你的小伙伴VSCode已经在应用菜单里等你了!
1643 23
|
7月前
|
Ubuntu 搜索推荐 Linux
详解Ubuntu的strings与grep命令:Linux开发的实用工具。
这就是Ubuntu中的strings和grep命令,透明且强大。我希望你喜欢这个神奇的世界,并能在你的Linux开发旅程上,通过它们找到你的方向。记住,你的电脑是你的舞台,在上面你可以做任何你想做的事,只要你敢于尝试。
392 32
|
8月前
|
Ubuntu Linux 编译器
在Ubuntu Linux系统下如何搭建并安装EDK2
以上就是在Ubuntu Linux系统下搭建并安装EDK2的过程。这个过程可能会有些复杂,但只要按照步骤一步步来,应该不会有太大问题。如果在过程中遇到任何问题,都可以在网上找到相应的解决方案。希望这个指南能对你有所帮助!
335 17
|
9月前
|
Ubuntu 安全 Linux
Linux错误排查:解决Ubuntu 20.4执行sudo apt-get update时出现的libnettle.so.6错误。
很有可能在你得到解决方案时,你也学到了不少Linux修复技巧。祝你处理计算机问题时顺利如麻!永远记得,各种问题总是像老鼠一样从意想不到的地方冒出来。但记住,不管它们跑到哪里,最终都逃不过你的捕鼠器。盖起你的计算机,拾起你的代码,大步向前!
271 28
|
3月前
|
存储 Ubuntu iOS开发
在Ubuntu 22.04系统上安装libimobiledevice的步骤
为了获取更多功能或者解决可能出现问题,请参考官方文档或者社区提供支持。
194 14
|
7月前
|
Ubuntu 定位技术 开发工具
在Ubuntu 20.04系统中安装SLAM库的具体操作步骤
以上是在Ubuntu 20.04系统中安装SLAM库的具体操作步骤。就像积木游戏,需要按照正确的步骤,适时地添加正确的部件,才能够构建出我们想要的积木模型。在现实操作中可能会遇到各种问题,就像积木构建中的各种困难,我们要有耐心和决心去解决它们,最后得到我们想要的结果。希望这个有趣的积木游戏比方能帮助你更好地理解SLAM库的安装过程,并在实际操作中得到应用。
177 34
|
7月前
|
Ubuntu Linux 定位技术
在Ubuntu 20.04系统安装Matlab R2021a步骤
希望你可以充分享受这场旅行,从无知的迷雾中找到通向智慧的路。好好装备你的 Linux 旅行箱吧,因为还有很多其他的知识世界等待你去探索和征服。在知识的海洋里,只有勇敢的探索者才能找到自己的道路。快乐旅行!
678 23
|
存储 Prometheus 监控
在Ubuntu系统上安装与配置Prometheus的步骤
通过以上步骤,您应该已经成功在Ubuntu系统上安装并配置了Prometheus。您现在可以开始使用Prometheus收集和分析您的系统和应用程序的指标数据了。
964 1