Linux framebuffer测试程序
Linux framebuffer的框架非常简单, 对于应用程序就是操作一块内存(俗称帧缓存), 当然也有可能是双缓存, 一般用于高帧率场景, 一块帧在填充数据时, 另一块在显示, 接着对调过来,
那通过设置哪里告知驱动层读取哪块帧数据呢? 答案是用vinfo.xoffset, vinfo.yoffset
需要注意的是, 无论用write()、还是mmap()后直接操作内存都只是填充内存而已, 并不代表能够立马显示, 这得看驱动, 如果驱动实现了自刷新(不断从帧缓存拿数据刷到LCD上), 那填充数据到帧缓存就会立马显示出来,
如果驱动没有实现,那应用程序需要主动的调用 ioctl(fp, FBIOPAN_DISPLAY, &vinfo);, 告知驱动可以刷数据了, 如果这都没显示出来, 估计驱动没实现FBIOPAN_DISPLAY功能。
示例代码:(驱动实现自刷新, 应用依次显示黄、蓝、红,最后画线)
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h> #define RED 0xF800
#define YELLOW 0xFFE0
#define BLUE 0x001F
#define WHITE 0xFFFF
#define BLACK 0x0000 void fill_color16(short *fb_addr, short bit_map, int psize)
{
int i;
for(i=; i<psize; i++) {
*fb_addr = bit_map;
fb_addr++;
}
} int main ()
{
int fp=;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long screensize=;
char *fbp = NULL, *test_fbp=NULL;
int x = , y = ;
long location = ;
int i;
int num = ;
int pix_size=; fp = open("/dev/graphics/fb0", O_RDWR); if(fp < ) {
printf("Error : Can not open framebuffer device/n");
exit();
} if(ioctl(fp, FBIOGET_FSCREENINFO, &finfo)){
printf("Error reading fixed information/n");
exit();
} if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){
printf("Error reading variable information/n");
exit();
} screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / ; printf("The phy mem = 0x%x, total size = %d(byte)\n", finfo.smem_start, finfo.smem_len);
printf("xres = %d, yres = %d, bits_per_pixel = %d\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
printf("So the screensize = %d(byte), using %d frame\n", screensize, finfo.smem_len/screensize);
printf("vinfo.xoffset = %d, vinfo.yoffset = %d\n", vinfo.xoffset, vinfo.yoffset);
printf("vinfo.vmode is :%d\n", vinfo.vmode);
printf("finfo.ypanstep is :%d\n", finfo.ypanstep);
printf("vinfo.red.offset=0x%x\n", vinfo.red.offset);
printf("vinfo.red.length=0x%x\n", vinfo.red.length);
printf("vinfo.green.offset=0x%x\n", vinfo.green.offset);
printf("vinfo.green.length=0x%x\n", vinfo.green.length);
printf("vinfo.blue.offset=0x%x\n", vinfo.blue.offset);
printf("vinfo.blue.length=0x%x\n", vinfo.blue.length);
printf("vinfo.transp.offset=0x%x\n", vinfo.transp.offset);
printf("vinfo.transp.length=0x%x\n", vinfo.transp.length); fbp =(char *)mmap(, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,);
if ((int)fbp == -)
{
printf ("Error: failed to map framebuffer device to memory./n");
exit ();
}
printf("Get virt mem = %p\n", fbp); pix_size = vinfo.xres * vinfo.yres;
/* using first frame, for FBIOPAN_DISPLAY
* 当刷新需要调用FBIOPAN_DISPLAY, 要告知驱动刷哪块帧, 用到下面两个参数
* 如果使用第二帧buffer -> vinfo.xoffset = 0; vinfo.yoffset = vinfo.yres;
*/
vinfo.xoffset = ;
vinfo.yoffset = ; /* show color loop */
while(num--) {
printf("\ndrawing YELLOW......\n");
fill_color16((short *)fbp, YELLOW, pix_size);
//ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
sleep(); printf("\ndrawing BLUE......\n");
fill_color16((short *)fbp, BLUE, pix_size);
//ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
sleep(); printf("\ndrawing RED......\n");
fill_color16((short *)fbp, RED, pix_size);
//ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
sleep();
}
#if 1
/*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/
x = ;
y = ;
location = x * (vinfo.bits_per_pixel / ) + y * finfo.line_length;
test_fbp = fbp + location;
printf("draw line.......\n");
for(i = ; i < (vinfo.xres - x); i++)
*test_fbp++ = i+; //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
#endif munmap(fbp, screensize); /*解除映射*/ close (fp);
return ;
}
当然用read()/write(), 也可以, 就是效率非常低, 太多系统调用导致系统在用户态和kernel态切换, 而且每次还传输一个字节, 但作为例子可以参考一下:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h> #define RED 0xF800
#define YELLOW 0xFFE0
#define BLUE 0x001F
#define WHITE 0xFFFF
#define BLACK 0x0000 int main ()
{
int fp=;
struct fb_var_screeninfo vinfo;
int i;
int pix_size=;
unsigned char color1, color2; fp = open("/dev/graphics/fb0", O_RDWR); if(fp < ) {
printf("Error : Can not open framebuffer device/n");
exit();
} if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){
printf("Error reading variable information/n");
exit();
} pix_size = vinfo.xres * vinfo.yres;
color1 = ;
color2 = 0xf8;
for(i=; i<pix_size; i++) {
write(fp, &color1, );
write(fp, &color2, );
} close (fp);
return ;
}
Linux framebuffer测试程序的更多相关文章
- Linux Framebuffer驱动剖析之一—软件需求
嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT两方面的原创技术分享,稍后会发布嵌入式企鹅圈的2 ...
- Linux Framebuffer save as picture
/********************************************************************************* * Linux Framebuff ...
- Linux Framebuffer驱动剖析之中的一个—软件需求
嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT双方面的原创技术分享,稍后会公布嵌入式企鹅圈的2 ...
- Linux Framebuffer驱动框架之二软件架构(未完待续)【转】
本文转载自:http://blog.csdn.net/gqb_driver/article/details/12918547 /************************************ ...
- Linux Framebuffer 驱动框架之一概念介绍及LCD硬件原理【转】
本文转载自:http://blog.csdn.net/liuxd3000/article/details/17464779 一.基本概念 帧缓冲(Framebuffer)是Linux系统为显示设备提供 ...
- framebuffer测试程序
/* framebuffer简单测试程序 网上转载 很多次 的程序 :-) */ #include <stdio.h> #include <stdlib.h> #include ...
- 【转】Linux Framebuffer
全面的framebuffer详解 一.FrameBuffer的原理 FrameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口. Linux是工作在保护模式下,所以用户态进程是无法象D ...
- Linux Framebuffer驱动剖析之二—驱动框架、接口实现和使用
深入分析LinuxFramebuffer子系统的驱动框架.接口实现和使用. 一.LinuxFramebuffer的软件需求 上一篇文章详细阐述了LinuxFramebuffer的软件需求(请先理解第一 ...
- Linux framebuffer显示bmp图片【转】
本文转载自:http://blog.csdn.net/luxiaoxun/article/details/7622988 framebuffer简介 帧缓冲(framebuffer)是Linux为显示 ...
随机推荐
- BZOJ_2882_工艺_后缀数组
BZOJ_2882_工艺_后缀数组 Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且 ...
- Healwire Online Pharmacy 3.0 Cross Site Request Forgery / Cross Site Scripting
Healwire Online Pharmacy version 3.0 suffers from cross site request forgery and cross site scriptin ...
- MYSQL——数据库存储引擎!
本人安装mysql版本为:mysql Ver 14.14 Distrib 5.7.18, for Win64 (x86_64),查看mysql的版本号方式:cmd-->mysql --vers ...
- 关于throw、throws、try--catch的问题
首先回顾概念 throws表示出现异常的一种可能性,并不一定会发生这些异常 throw则是抛出了异常,执行throw则一定抛出了某种异常 try--catch try语句用大括号{}指定了一段代码,该 ...
- WebGL学习之纹理贴图
为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ...
- TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)
这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟 ...
- Word页眉、页码的使用:利用分隔符设置指定页显示页眉,解决页码显示{PAGE \* MERGEFORMAT}问题
不常编辑对文档有格式要求的朋友来说,偶尔需要编辑指定格式页眉页码的word文档时,会一时不记得如何使用,在网上搜索半天,异常烦躁. 特整理一下,记录下来,备不时只需. 以下操作环境为word2016. ...
- Vue.js-10:第十章 - 组件间的数据通信
一.前言 在上一章的学习中,我们继续学习了 Vue 中组件的相关知识,了解了在 Vue 中如何使用组件的 data.prop 选项.在之前的学习中有提到过,组件是 Vue 中的一个非常重要的概念,我们 ...
- ASP.NET Core中使用GraphQL - 最终章 Data Loader
ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间 ...
- BoltDB简单使用教程
1.BoltDB简介 Bolt是一个纯粹Key/Value模型的程序.该项目的目标是为不需要完整数据库服务器(如Postgres或MySQL)的项目提供一个简单,快速,可靠的数据库. BoltDB只需 ...