通过Framebuffer刷屏使得屏幕显示红色
文章的开始,想要申明一下:我的目的是在整个屏幕上显示红色。关于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刷屏使得屏幕显示红色相关推荐
- 关于一些自己需要的资料记录
fdk-aac 编码:fdk-aac交叉编译与使用_Nomidia的博客-CSDN博客_fdk-aac 交叉编译 解码:examples/decode/src/main.c · mazcpnt/fdk ...
- 干货:esp32彩屏自制太空人主题透明手表!
#创作来源# 牛年春节前看了稚晖君自制的百大up奖杯视频,用到了一块分光棱镜,透明的玻璃中显示动感的画面超有感觉,一下子就把我吸引了,于是就赶着快递停运前把分光棱镜买了回来,想着春节假期体验一把,奈何 ...
- 追踪高频交易——华尔街猎狼者(上)
(文章改编自著名金融作家Michael Lewis新作"Flash Boys: A Wall Street Revolt",原文载于<纽约时报>,华尔街见闻网站整理) ...
- 用QEMU模拟ARM开发板,搭建Linux kernel运行环境
前言 有的时候我们想调试linux kernel或者linux应用程序,但是又没有硬件环境,这个时候可以选择用模拟器的方法,模拟出一个硬件环境. Android emulator Android系统的 ...
- Esp8266+TFT1.44(ST7735)实现基本的时钟功能
我们基于简单的ESP8266开发板和一块液晶显示屏来实现简单的时钟功能,出发点是为了熟悉TFT_eSPI这个库,设计一个简单的界面. 1.效果图: 2.所需硬件: Esp8266+TFT显示屏(分辨率 ...
- Android Camera OpenGL FBO的理解
背景概念: 首先,Android显示系统中,系统默认的渲染器是OpenGL,混合使用skia,各个厂商可能有不同的实现,大部分都是OpenGL. Android在系统启动时,经过BootLoader启 ...
- OpenGL——GPU图形渲染管线
OpenGL渲染管线 OpenGL本身并不是一个API,他仅仅是一个由Khronos组织制定并维护的规范:OpenGL规范严格规定了每个函数改如何执行,以及他们的输出值,至于内部具体每个函数是如何实现 ...
- 【gec6818学习】
一.学习目标 (一)项目需求: <基于GEC6818的多媒体终端系统> 基本需求: 相册功能: 音乐功能: 视频功能: 优化需求: 界面优美 具有一定主题 系统流畅 创新功能(登录界面.开 ...
- Linux Framebuffer编程之lcd屏幕显示jpeg图像
开发环境 虚拟机Ubuntu 16.04 编辑器VsCode 交叉编译工具 arm-linux-gnueabihf 已制作文件系统,有lcd相关驱动 正点原子ZYNQ7010启明星开发板 + ALIE ...
最新文章
- OpenCV 【十一】—— 图像去畸变,对极约束之undistort,initUndistortRectifyMap,undistort
- python 连续矫正_Python实现系统时间自动校正 | 学步园
- redis企业级应用(下)-如何维护redis的key
- log4jdbc oracle,通过weblogic配置log4jdbc数据源,在项目中使用该数据源,输出sql
- SAP Spartacus forms.scss的引用问题
- 使用ndk standalone工具链来编译某个平台下的库
- 【Python CheckiO 题解】Easy Unpack
- navicat 官方使用手册,中文版,快捷键大全
- 计组之数据运算:4、移位运算
- 某Q娱乐网emlog程序整站源码
- mysql主从不同步问题_mysql主从之间不同步问题
- ndows定时任务_百度经验,windows服务器:编写bat脚本,创建定时任务
- GOOGLE 分布式系统关键技术论文分析
- form表单自动回车提交
- 论文阅读笔记(十二)——U-Net: Convolutional Networks for Biomedical Image Segmentation
- TSPL学习笔记(2):过程和变量绑定
- 数学建模基本模型(一) 优化模型
- 腾讯程序员与医生相恋,却被女方父母拆散,你们不能在一起
- SAP:传输请求SE09->STMS
- 1024人工智能和大数据应用高峰论坛
热门文章
- (附源码)springboot的房产中介系统 毕业设计 312341
- 秀恩爱分得快 (25 分)
- 机器学习 | 实验五:LDA
- 堡垒机jumpserver 搭建与使用
- Re19:读论文 Paragraph-level Rationale Extraction through Regularization: A case study on European Court
- html实现在线展示PDF,html展示 pdf 利器
- Commons Logging 的使用方法
- Mac 键盘与鼠标的映射
- echarts series not exists. Legend data should be same with series name or data name.问题
- JavaScript 中获取光标位置