文章的开始,想要申明一下:我的目的是在整个屏幕上显示红色。关于Framebuffer的原理知识我很少涉及,请读者自己查阅相关书籍或者上网查找资料。

开发环境:

物理机(不是虚拟机)Ubuntu 11.04

最近在作一个视频采集显示的东西,要用到Framebuffer,就看了点相关的知识。在这里稍微总结一下。

Framebuffer对应的文件是/dev/fb0。

这里我说明两点:

1.如果在/dev目录下没有fb0文件,那就重新启动试试。一开始我的电脑上也没有fb0文件,我就瞎捣鼓了一下Nvidia X Server Settings,修改了显示器设置参数,又重新启动了电脑就出现fb0文件了,具体原因我不知道(根据我的做事原则-用最简单、最有效、最直接的方法解决问题。我的目的是要显示器显示红色,既然我搞出来fb0文件了,离目的又进了一步,也就没有深究为什么)。

2.修改下fb0文件的权限,否则会在以后运行程序时出现无法打开文件的错误。

sudo chmod 666 /dev/fb0

操作Framebuffer的步骤如下:

1.打开文件:open函数

2.映射帧缓冲到应用程序空间:mmap函数

3.操作映射后的内存空间,在这里就是将红色对应的RGB和透析度的数值写到相关的内存空间内。

4.释放映射空间和关闭文件描述符。

程序总共两个:

1.第一个程序如下:

很简单的一个程序,就是打印出Framebuffer的一些相关信息,就是fb_var_screeninfo 和fb_fix_screeninfo 两个结构体主要成员的打印。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>int
main (int argc,char **argv ){int fb_fd=-1;struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo finfo;fb_fd = open("/dev/fb0",O_RDWR);if (fb_fd < 0){printf("Error : Can not open framebuffer device\n");exit(EXIT_FAILURE);}if(ioctl(fb_fd,FBIOGET_FSCREENINFO,&finfo)){printf("Error reading fixed information\n");exit(EXIT_FAILURE);}if (ioctl(fb_fd,FBIOGET_VSCREENINFO,&vinfo)){printf("Error reading variable information\n");exit(3);}printf("the fixed information is as follow:\n");printf("id=%s\n",finfo.id);printf("sem_start=%lx\n",finfo.smem_start);printf("smem_len=%u\n",finfo.smem_len);printf("type=%u\n",finfo.type);printf("line_length=%u\n",finfo.line_length);printf("mmio_start=%lu\n",finfo.mmio_start);printf("mmio_len=%d\n",finfo.mmio_len);printf("variable information is as follow:\n");printf("The xres is :%u\n",vinfo.xres);printf("The yres is :%u\n",vinfo.yres);printf("xres_virtual=%u\n",vinfo.xres_virtual);printf("yres_virtual=%u\n",vinfo.yres_virtual);printf("xoffset=%u\n",vinfo.xoffset);printf("yoffset=%u\n",vinfo.yoffset);printf("bits_per_pixel is :%u\n",vinfo.bits_per_pixel);printf("red.offset=%u\n",vinfo.red.offset);printf("red.length=%u\n",vinfo.red.length);printf("red.msb_right=%u\n",vinfo.red.msb_right);printf("green.offset=%d\n",vinfo.green.offset);printf("green.length=%d\n",vinfo.green.length);printf("green.msb_right=%d\n",vinfo.green.msb_right);printf("blue.offset=%d\n",vinfo.blue.offset);printf("blue.length=%d\n",vinfo.blue.length);printf("blue.msb_right=%d\n",vinfo.blue.msb_right);printf("transp.offset=%d\n",vinfo.transp.offset);printf("transp.length=%d\n",vinfo.transp.length);printf("transp.msb_right=%d\n",vinfo.transp.msb_right);printf("height=%x\n",vinfo.height);printf("width=%x\n",vinfo.width);close (fb_fd);return 0;
}

输出结果如下:

the fixed information is as follow:
id=VESA VGA
sem_start=cf000000
smem_len=1245184
type=0
line_length=2560
mmio_start=0
mmio_len=0
variable information is as follow:
The xres is :640
The yres is :480
xres_virtual=640
yres_virtual=480
xoffset=0
yoffset=0
bits_per_pixel is :32
red.offset=16
red.length=8
red.msb_right=0
green.offset=8
green.length=8
green.msb_right=0
blue.offset=0
blue.length=8
blue.msb_right=0
transp.offset=24
transp.length=8
transp.msb_right=0
height=ffffffff
width=ffffffff

有几个输出要重视:

The xres is :640

The yres is :480//虚拟控制台屏幕的分辨率(虚拟控制台,即:Ctrl+Alt+Fn(n=1,2,3,4,5,6)时进入的控制台。我的机器是物理机,虚拟机没有尝试过)

bits_per_pixel is :32//一个像素点占用32位,也就是说明像素点对应的内存中存放的RGB32(R、G、B各占8位,剩下的八位用来存放透析度(不知道是什么东西,也没管它))数据。这里有个问题很重要啊:到底这32位的数据怎么存放的的呢?????最低的八位放R、G、B还是透析度数据呢。。。。。。接着往下看---------

red.offset=16//看来R数据放在32数据中的16-23上

red.length=8

red.msb_right=0//指的是数据的最高有效位在最左边


green.offset=8//看来G数据放在32数据中的8-15上

green.length=8

green.msb_right=0


blue.offset=0//看来B数据放在32数据中的0-7上

blue.length=8

blue.msb_right=0


transp.offset=24//看来透析度数据放在32数据中的24-31上

transp.length=8

transp.msb_right=0


以上内容一定要明白,否则先别往下看,查查资料先把理论搞明白再说。



2.第二个程序如下:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>#define IMAGE_W 640  //对应上一个程序的xres
#define IMAGE_H 480   //对应上一个程序的yrestypedef struct {char red;char blue;char green;char trans;
} PIXEL;         //自定义的结构体用于存放一个像素点的颜色数据,这里比较简单就是存放红色的RGB和透析度数据int
main(){PIXEL pixel;pixel.trans=0;pixel.red=255;pixel.green=0;pixel.blue=0;   //查表得到。。。。程序后面有插图int fb_fd=0,i=0,j=0;unsigned long int *fbp,*mmap_start;unsigned long buffersize;char * cur_pix;struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo finfo;fb_fd = open("/dev/fb0",O_RDWR);if (fb_fd < 0){printf("Error : Can not open framebuffer device\n");exit(1);}if(ioctl(fb_fd,FBIOGET_FSCREENINFO,&finfo)){printf("Error reading fixed information\n");exit(2);}if (ioctl(fb_fd,FBIOGET_VSCREENINFO,&vinfo)){printf("Error reading variable information\n");exit(3);}/*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);*/buffersize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;mmap_start=(unsigned long int *)mmap(0,buffersize,PROT_READ | PROT_WRITE,MAP_SHARED,fb_fd,0);if((long int )mmap_start==-1){perror("mmap error!\n");exit(EXIT_FAILURE);}fbp=mmap_start;for(i=0;i<IMAGE_H;i++){for(j=0;j<IMAGE_W;j++){cur_pix=(char *)fbp;cur_pix[0]=pixel.blue;cur_pix[1]=pixel.green;cur_pix[2]=pixel.red;cur_pix[3]=pixel.trans;fbp++;}}munmap(mmap_start,buffersize);close (fb_fd);return 0;}
}

查表可得红色对应的RGB数据是0xFF0000 。


现在请按下组合键(Ctrl+Alt+Fn(n=1,2,3,4,5,6))进入虚拟控制台,通过cd命令转到存放源程序的目录下,编译后运行,是不是屏幕全变成红色了呢?

通过Framebuffer刷屏使得屏幕显示红色相关推荐

  1. 关于一些自己需要的资料记录

    fdk-aac 编码:fdk-aac交叉编译与使用_Nomidia的博客-CSDN博客_fdk-aac 交叉编译 解码:examples/decode/src/main.c · mazcpnt/fdk ...

  2. 干货:esp32彩屏自制太空人主题透明手表!

    #创作来源# 牛年春节前看了稚晖君自制的百大up奖杯视频,用到了一块分光棱镜,透明的玻璃中显示动感的画面超有感觉,一下子就把我吸引了,于是就赶着快递停运前把分光棱镜买了回来,想着春节假期体验一把,奈何 ...

  3. 追踪高频交易——华尔街猎狼者(上)

    (文章改编自著名金融作家Michael Lewis新作"Flash Boys: A Wall Street Revolt",原文载于<纽约时报>,华尔街见闻网站整理) ...

  4. 用QEMU模拟ARM开发板,搭建Linux kernel运行环境

    前言 有的时候我们想调试linux kernel或者linux应用程序,但是又没有硬件环境,这个时候可以选择用模拟器的方法,模拟出一个硬件环境. Android emulator Android系统的 ...

  5. Esp8266+TFT1.44(ST7735)实现基本的时钟功能

    我们基于简单的ESP8266开发板和一块液晶显示屏来实现简单的时钟功能,出发点是为了熟悉TFT_eSPI这个库,设计一个简单的界面. 1.效果图: 2.所需硬件: Esp8266+TFT显示屏(分辨率 ...

  6. Android Camera OpenGL FBO的理解

    背景概念: 首先,Android显示系统中,系统默认的渲染器是OpenGL,混合使用skia,各个厂商可能有不同的实现,大部分都是OpenGL. Android在系统启动时,经过BootLoader启 ...

  7. OpenGL——GPU图形渲染管线

    OpenGL渲染管线 OpenGL本身并不是一个API,他仅仅是一个由Khronos组织制定并维护的规范:OpenGL规范严格规定了每个函数改如何执行,以及他们的输出值,至于内部具体每个函数是如何实现 ...

  8. 【gec6818学习】

    一.学习目标 (一)项目需求: <基于GEC6818的多媒体终端系统> 基本需求: 相册功能: 音乐功能: 视频功能: 优化需求: 界面优美 具有一定主题 系统流畅 创新功能(登录界面.开 ...

  9. Linux Framebuffer编程之lcd屏幕显示jpeg图像

    开发环境 虚拟机Ubuntu 16.04 编辑器VsCode 交叉编译工具 arm-linux-gnueabihf 已制作文件系统,有lcd相关驱动 正点原子ZYNQ7010启明星开发板 + ALIE ...

最新文章

  1. OpenCV 【十一】—— 图像去畸变,对极约束之undistort,initUndistortRectifyMap,undistort
  2. python 连续矫正_Python实现系统时间自动校正 | 学步园
  3. redis企业级应用(下)-如何维护redis的key
  4. log4jdbc oracle,通过weblogic配置log4jdbc数据源,在项目中使用该数据源,输出sql
  5. SAP Spartacus forms.scss的引用问题
  6. 使用ndk standalone工具链来编译某个平台下的库
  7. 【Python CheckiO 题解】Easy Unpack
  8. navicat 官方使用手册,中文版,快捷键大全
  9. 计组之数据运算:4、移位运算
  10. 某Q娱乐网emlog程序整站源码
  11. mysql主从不同步问题_mysql主从之间不同步问题
  12. ndows定时任务_百度经验,windows服务器:编写bat脚本,创建定时任务
  13. GOOGLE 分布式系统关键技术论文分析
  14. form表单自动回车提交
  15. 论文阅读笔记(十二)——U-Net: Convolutional Networks for Biomedical Image Segmentation
  16. TSPL学习笔记(2):过程和变量绑定
  17. 数学建模基本模型(一) 优化模型
  18. 腾讯程序员与医生相恋,却被女方父母拆散,你们不能在一起
  19. SAP:传输请求SE09->STMS
  20. 1024人工智能和大数据应用高峰论坛

热门文章

  1. (附源码)springboot的房产中介系统 毕业设计 312341
  2. 秀恩爱分得快 (25 分)
  3. 机器学习 | 实验五:LDA
  4. 堡垒机jumpserver 搭建与使用
  5. Re19:读论文 Paragraph-level Rationale Extraction through Regularization: A case study on European Court
  6. html实现在线展示PDF,html展示 pdf 利器
  7. Commons Logging 的使用方法
  8. Mac 键盘与鼠标的映射
  9. echarts series not exists. Legend data should be same with series name or data name.问题
  10. JavaScript 中获取光标位置