/dev/fb0入门练习

From: http://sunnyshineboy.blog.163.com/blog/static/20281511820124121118700/


大家都知道Unix/Linux系统是由命令驱动的。那么最基本的系统是命令行的(就是想DOS一样的界面)。X-Window-System是Unix/Linux上的图形系统,它是通过X-Server来控制硬件的。但有一些Linux的发行版在引导的时候就会在屏幕上出现图形,这时的图形是不可能由X来完成的,那是什么机制呢?答案是FrameBuffer。
FrameBuffer不是一个图形系统,更不是窗口系统。它比X要低级,简单来说FrameBuffer就是一种机制的实现。这种机制是把屏幕上的每个点映射成一段线性内存空间,程序可以简单的改变这段内存的值来改变屏幕上某一点的颜色。X的高度可移植性就是来自于这种机制,不管是在那种图形环境下,只要有这种机制的实现就可以运行X。所以在几乎所有的平台上都有相应的X版本的移植。
好了,闲话少说,下面我们来看看可以利用FrameBuffer来干点什么。首先看看你是否有了相应的驱动:找一下在/dev/下是否有fb*这个设备文件,这是个字符类的特殊文件。
代码:
ls -l  /dev/fb0   crw-rw---- 1 root video 29, 0 Jan 27 15:32 /dev/fb0
如果没有这个文件也可以找找其他的比如:/dev/fb1,/dev/fb2...如果找不到这些文件,那就得重新编译内核了。下面假设存在这个文件/dev/fb0,这就是FrameBuffer的设备文件。
有了这个我们可以play with FrameBuffer了。(一下的操作不一定要在X下,可以在启动了FrameBuffer的虚拟控制台下)
代码:
cat /dev/fb0 > sreensnap    ls -l sreensnap -rw-r--r-- 1    wsw wsw 6291456 Jan 27 21:30 sreensnap
我们得到了一个恰好6M的文件,再做下面的操作:
代码:
clear /*清楚屏幕的输出*/ cat sreensnap > /dev/fb0
是不是奇怪的事情发生了?好像是中了病毒一般?屏幕又恢复了以前的状态?不用着急,
代码:
clear
这样屏幕就正常了。

通过以上的操作,我想你也猜到了。文件/dev/fb0就是控制屏幕上的每一点的颜色的文件。我们可以写程序来改变这个文件的内容,就可以方便的在屏幕上画图了:-)

我下面就来写一个小程序,探测一下屏幕的属性

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

int main () {
 int fp=0;
 struct fb_var_screeninfo vinfo;
 struct fb_fix_screeninfo finfo;
 fp = open ("/dev/fb0",O_RDWR);

 if (fp < 0){
  printf("Error : Can not open framebuffer device/n");
  exit(1);
 }

 if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
  printf("Error reading fixed information/n");
  exit(2);
 }
 
 if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
  printf("Error reading variable information/n");
  exit(3);
 }

 printf("The mem is :%d/n",finfo.smem_len);
 printf("The line_length is :%d/n",finfo.line_length);
 printf("The xres is :%d/n",vinfo.xres);
 printf("The yres is :%d/n",vinfo.yres);
 printf("bits_per_pixel is :%d/n",vinfo.bits_per_pixel);
 close (fp);
}
struct fb_var_screeninfo 和 struct fb_fix_screeninfo 两个数据结构是在/usr/include/linux/fb.h中定义的,里面有些有趣的值:(都是无符号32位的整数)
 
在fb_fix_screeninfo中有
__u32 smem_len 是这个/dev/fb0的大小,也就是内存大小。
__u32 line_length 是屏幕上一行的点在内存中占有的空间,不是一行上的点数。
在fb_var_screeninfo 中有
__u32 xres ,__u32 yres 是x和y方向的分辨率,就是两个方向上的点数。
__u32 bits_per_pixel 是每一点占有的内存空间。

把上面的程序编译以后运行,在我的机器上的结果如下
The mem is :6291456
The line_length is :4096 T
he xres is :1024
The yres is :768
bits_per_pixel is :32
//这样子在调试的时候相当的重要和完善了呀!!!!!
内存长度恰好是6M,每行占有4M的空间,分辨率是1024x768,色彩深度是32位。细心的你可能已经发现有些不对。屏幕上的点有1024x768=786432个,每个点占有32比特。屏幕一共的占有内存数为32x786432=25165824 就是3145728字节,恰好是3M但是上面的程序告诉我们有6M的存储空间。这是因为在现代的图形系统中大多有缓冲技术,显存中存有两页屏幕数据,这是方便快速的改变屏幕内容实现动画之类比较高的要求。关于这种缓冲技术有点复杂,我们目前先不讨论。对于我们来说只有这3M内存来存放这一个屏幕的颜色数据。
好了,现在你应该对FrameBuffer有一个大概的了解了吧。那么接下来你一定会想在屏幕上画一些东西,让我们先从画一个点开始吧。先说说我的想法:在类Unix系统中,一切东西都是文件。我们对屏幕的读写就可以转换成对/dev/fb0的读写。那么就把/dev/fb0用open打开,再用lseek定位要读写的位置,最后调用read或者write来操作。通过这么一大段的操作我们才完成了对一个点的读或者写。这种方法开销太大了。还有一种方法,我们把/dev/fb0映射到程序进程的内存空间中来,然后得到一个指向这段存储空间的指针,这样就可以方便的读写了。但是我们要知道能映射多少和该映射多少,这能很方便的从上面一个程序得出的参数来决定。
//内存当中的映射的关键的部分描述和介绍
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main () {
 int fp=0;
 struct fb_var_screeninfo vinfo;
 struct fb_fix_screeninfo finfo;
 long screensize=0;
 char *fbp = 0;
 int x = 0, y = 0;
 long location = 0;
 fp = open ("/dev/fb0",O_RDWR);

 if (fp < 0){
  printf("Error : Can not open framebuffer device/n");
  exit(1);
 }

 if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
  printf("Error reading fixed information/n");
  exit(2);
 }
 
 if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
  printf("Error reading variable information/n");
  exit(3);
 }

  screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
 /*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
 fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
   if ((int) fbp == -1)
     {
        printf ("Error: failed to map framebuffer device to memory./n");
        exit (4);
     }
/*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/
  x = 100;
  y = 100;
  location = x * (vinfo.bits_per_pixel / 8) + y  *  finfo.line_length;

  *(fbp + location) = 100;  /* 蓝色的色深 */  /*直接赋值来改变屏幕上某点的颜色*/
  *(fbp + location + 1) = 15; /* 绿色的色深*/  
  *(fbp + location + 2) = 200; /* 红色的色深*/  
  *(fbp + location + 3) = 0;  /* 是否透明*/ 
  munmap (fbp, screensize); /*解除映射*/
  close (fp);    /*关闭文件*/
  return 0;

}
但是有了这个基本的代码实现,我们可以很容易写一些DrawPoint之类的函数去包装一下低层的对线性存储空间的读写。但是有了画点的程序,再写出画线画圆的函数就不是非常困难了。

这些就是我对FrameBuffer的初步研究,匆忙之间写些东西不成文章,以后要写些更高级一点的函数的实现


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 多线程开发-等待线程结束pthread_join

1、函数原型 int pthread_join(pthread_t pid, void **value_ptr); pid&#xff1a;所等待的线程ID&#xff1b;value_ptr&#xff1a;通常设置为NULL&#xff0c;如果不为NULL&#xff0c;pthread_join将复制一份线程退出值到一个内存区域&#xff0c;并让*value_ptr指向该内…

SQL常用语句|创建表,设置主键......

新建表 create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default \默认值\ null ,[字段2] ntext null ,[字段3] datetime,[字段4] money null ,[字段5] int default 0,[字段6] Decimal (12,4) default 0,[字段7] image null ,) 删除…

如何Keil官网下载器件支持包Software Packs

步骤1&#xff1a;百度一下Keil&#xff0c;在搜索结果中点击打开官网 步骤2&#xff1a;在官网的搜索栏输入Software Packs&#xff0c;点击Go 步骤3&#xff1a;点击打开MDK Software Packs 步骤4&#xff1a;往下拉&#xff0c;找到自己需要的Pack 步骤5&#xff1a;以下载s…

为文档快速插入页眉和页脚

专业的文档往往需要配以漂亮的页眉、页脚等修饰性元素才会更加完美。在Word 2010中您不必再为设计漂亮页眉和页脚而大费周折&#xff0c;内置的“页眉样式库”和“页脚样式库”为您提供了丰富的选择余地。 &#xff08;1&#xff09;打开Word 2010文档&#xff0c;在“插入”选…

基于海思开发板的屏幕截图程序(一)

一直以来从事基于海思开发板的开发&#xff0c;但是每次想到“屏幕截图"&#xff0c;真的让人非常惭愧&#xff01; 参考网上的代码修改了下&#xff1a; #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <unistd.h> #…

[react] 如何给非控组件设置默认的值?

[react] 如何给非控组件设置默认的值&#xff1f; 表单元素依赖于状态(state)&#xff0c;表单元素需要默认值实时映射到状态的时候&#xff0c;就是受控组件 <input name"username" type"text" value{this.state.username} onChange{this.handleChan…

Linux 多线程开发-线程的属性-分离detached和连接joinable

1、描述 linux的POSIX线程分离状态决定一个线程以什么方式来终止。默认的分离状态是可连接态&#xff08;joinable&#xff09;&#xff0c;创建线程是参数设置为NULL&#xff0c;就是默认连接态&#xff0c;可以被pthread_join。 Linux的POSIX线程要么分离要么连接分别用一下…

oracle10g随服务器启动而自动启动(linux as 5)

http://blog.sina.com.cn/s/blog_5007d1b10100lq7g.html

[BBS]搭建开源论坛之Jforum搭配开源CKEDITOR

本文作者&#xff1a;sushengmiyan本文地址&#xff1a;http://blog.csdn.net/sushengmiyan/article/details/47946065使用默认的编辑器的时候&#xff0c;格式都无法保存。现在按照上节的方法更改了编辑器。今天再对编辑器进行更改&#xff0c;适应jforum.效果如下图了。记录几…

Linux cJSON库的使用、编译为cJSON动态库

参考 &#xff1a; https://blog.csdn.net/nanfeibuyi/article/details/86605314

[react] 怎么在React中引入其它的UI库,例如Bootstrap

[react] 怎么在React中引入其它的UI库&#xff0c;例如Bootstrap react-bootstrap是一个非常受欢迎的针对react封装过的bootstrap&#xff0c;它本身不包含css&#xff0c;所以也是需要使用bootstrap原生库。 在create-react-app建的项目目录中安装react-bootstrap。 npm inst…

基于海思开发板的屏幕截图程序(二)

针对 基于海思开发板的屏幕截图程序(一)作了改进&#xff0c;上篇文章的截图结果不正确的原因是&#xff1a;我公司的开发板上fb0中设置的图片格式为ARGB1555&#xff0c;但是我将它作为RGB565来使用&#xff0c;导致转换出来的图片数据不正确&#xff0c;所以压缩后的图片自然…

Linux 多线程开发-线程的结束pthread_kill和pthread_cancel

1、线程结束的方式 &#xff08;1&#xff09;线程函数中调用pthread_exit函数&#xff0c;不会导致对象析构&#xff0c;可以使用&#xff08;2&#xff09;线程所属的进程结束&#xff0c;进程调用exit&#xff0c;线程C对象不会销毁&#xff0c;不安全&#xff0c;属于被动…

Windows7休眠状态下载技巧攻略

Windows7休眠状态下载技巧攻略 你想让你的快车或者是迅雷通宵下载电影&#xff0c;而且还能省电么?或许你会说&#xff0c;我不关机&#xff0c;给迅雷和快车添加完下载任务&#xff0c;挂在那里不就可以了吗?这没错&#xff0c;开着电脑通宵下载是可以&#xff0c;但这样的方…

支付模块设计

1.背景知识 ssl:SSL为安全套接层&#xff0c;SSL 安全协议最初是由美国网景 Netscape Communication 公司设计开发的&#xff0c;全称为&#xff1a;安全套接层协议 (Secure Sockets Layer) &#xff0c; 它指定了在应用程序协议 ( 如 HTTP 、 Telnet 、 FTP) 和 TCP/IP 之间提…

NB-IOT/Lora/Zigbee/WIFI/蓝牙无线组网方式的对比

NB-IOT/Lora/Zigbee/WIFI/蓝牙无线组网方式的对比 LoRa LoRa(长 距离)是由Semtech公司开发的一种技术&#xff0c;典型工作频率在美国是915MHz&#xff0c;在欧洲是868MHz&#xff0c;在亚洲是433MHz。LoRa的物理层 (PHY)使用了一种独特形式的带前向纠错(FEC)的调频啁啾扩频技…

[react] React必须使用JSX吗?

[react] React必须使用JSX吗&#xff1f; 首先给出答案&#xff0c;不是必须的 只不过通过JSX&#xff0c;你可以简单明了的知道UI是怎样的 JSX is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like 个人简介 …

Qt 设置textEdit插入文本的字体、大小和颜色

1:、打开字体对话框选择字体 //用到头文件&#xff1a;#include <QFontDialog> void MainWindow::on_pushButton_font_clicked() {bool ok;QFont f QFontDialog::getFont(&ok, QFont("Consolas",9), this,"设置显示字体");if(ok){font f;} } …

开发板屏幕截图-适用于本公司海思和智源平台

C源码(screenshot.c)&#xff1a; #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <unistd.h> #include <time.h> #include <string.h> #include <fcntl.h> #include <malloc.h> #include <linu…

听小鹏讲废话之OSI

大家好&#xff0c;在下小鹏&#xff0c;大学刚毕业1年&#xff0c;目前从事华为网络设备工作。写这篇文章&#xff0c;有两个目的&#xff0c;第一&#xff0c;和大家分享学习的乐趣&#xff0c;俗话说&#xff0c;没有学不会的学生&#xff0c;只有教不会的老师&#xff1b;第…