作者:刘昊昱

博客:http://blog.csdn.net/liuhaoyutz

测试环境:Ubuntu 12.04终端模式

在网上找到一个很不错的介绍FrameBuffer相关知识的帖子,原帖网址如下:http://bbs.chinaunix.net/thread-1932291-1-1.html,现把其中测试FrameBuffer的应用程序代码转帖过来,方便分析学习:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
char *frameBuffer = 0;//打印fb驱动中fix结构信息,注:在fb驱动加载后,fix结构不可被修改。
void
printFixedInfo ()
{printf ("Fixed screen info:\n""\tid: %s\n""\tsmem_start:0x%lx\n""\tsmem_len:%d\n""\ttype:%d\n""\ttype_aux:%d\n""\tvisual:%d\n""\txpanstep:%d\n""\typanstep:%d\n""\tywrapstep:%d\n""\tline_length: %d\n""\tmmio_start:0x%lx\n""\tmmio_len:%d\n""\taccel:%d\n""\n",finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,finfo.ywrapstep, finfo.line_length, finfo.mmio_start,finfo.mmio_len, finfo.accel);
}//打印fb驱动中var结构信息,注:fb驱动加载后,var结构可根据实际需要被重置
void
printVariableInfo ()
{printf ("Variable screen info:\n""\txres:%d\n""\tyres:%d\n""\txres_virtual:%d\n""\tyres_virtual:%d\n""\tyoffset:%d\n""\txoffset:%d\n""\tbits_per_pixel:%d\n""\tgrayscale:%d\n""\tred: offset:%2d, length: %2d, msb_right: %2d\n""\tgreen: offset:%2d, length: %2d, msb_right: %2d\n""\tblue: offset:%2d, length: %2d, msb_right: %2d\n""\ttransp: offset:%2d, length: %2d, msb_right: %2d\n""\tnonstd:%d\n""\tactivate:%d\n""\theight:%d\n""\twidth:%d\n""\taccel_flags:0x%x\n""\tpixclock:%d\n""\tleft_margin:%d\n""\tright_margin: %d\n""\tupper_margin:%d\n""\tlower_margin:%d\n""\thsync_len:%d\n""\tvsync_len:%d\n""\tsync:%d\n""\tvmode:%d\n""\n",vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual,vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel,vinfo.grayscale, vinfo.red.offset, vinfo.red.length,vinfo.red.msb_right,vinfo.green.offset, vinfo.green.length,vinfo.green.msb_right, vinfo.blue.offset, vinfo.blue.length,vinfo.blue.msb_right, vinfo.transp.offset, vinfo.transp.length,vinfo.transp.msb_right, vinfo.nonstd, vinfo.activate,vinfo.height, vinfo.width, vinfo.accel_flags, vinfo.pixclock,vinfo.left_margin, vinfo.right_margin, vinfo.upper_margin,vinfo.lower_margin, vinfo.hsync_len, vinfo.vsync_len,vinfo.sync, vinfo.vmode);
}//画大小为width*height的同色矩阵,8alpha+8reds+8greens+8blues
void
drawRect_rgb32 (int x0, int y0, int width,int height, int color)
{const int bytesPerPixel = 4;const int stride = finfo.line_length / bytesPerPixel;int *dest = (int *) (frameBuffer)+ (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);int x, y;for (y = 0; y < height; ++y){for (x = 0; x < width; ++x){dest[x] = color;}dest += stride;}
}//画大小为width*height的同色矩阵,5reds+6greens+5blues
void
drawRect_rgb16 (int x0, int y0, int width,int height, int color)
{const int bytesPerPixel = 2;const int stride = finfo.line_length / bytesPerPixel;const int red = (color & 0xff0000) >> (16 + 3);const int green = (color & 0xff00) >> (8 + 2);const int blue = (color & 0xff) >> 3;const short color16 = blue | (green << 5) | (red << (5 +6));short *dest = (short *) (frameBuffer)+ (y0 + vinfo.yoffset) * stride + (x0 +vinfo.xoffset);int x, y;for (y = 0; y < height; ++y){for (x = 0; x < width; ++x){dest[x] = color16;}dest += stride;}
}//画大小为width*height的同色矩阵,5reds+5greens+5blues
void
drawRect_rgb15 (int x0, int y0, int width,int height, int color)
{const int bytesPerPixel = 2;const int stride = finfo.line_length / bytesPerPixel;const int red = (color & 0xff0000) >> (16 + 3);const int green = (color & 0xff00) >> (8 + 3);const int blue = (color & 0xff) >> 3;const short color15 = blue | (green << 5) | (red << (5 + 5))| 0x8000;short *dest = (short *) (frameBuffer)+ (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);int x, y;for (y = 0; y < height; ++y){for (x = 0; x < width; ++x){dest[x] = color15;}dest += stride;}
}void
drawRect (int x0, int y0, int width, intheight, int color)
{switch (vinfo.bits_per_pixel){case 32:drawRect_rgb32 (x0, y0, width, height, color);break;case 16:drawRect_rgb16 (x0, y0, width, height, color);break;case 15:drawRect_rgb15 (x0, y0, width, height, color);break;default:printf ("Warning: drawRect() not implemented for color depth%i\n",vinfo.bits_per_pixel);break;}
}#define PERFORMANCE_RUN_COUNT 5
void
performSpeedTest (void *fb, int fbSize)
{int i, j, run;struct timeval startTime, endTime;unsigned long long results[PERFORMANCE_RUN_COUNT];unsigned long long average;unsigned int *testImage;unsigned int randData[17] = {0x3A428472, 0x724B84D3, 0x26B898AB,0x7D980E3C, 0x5345A084,0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33,0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B,0x5F2C22FB, 0x6A742130};printf ("Frame Buffer Performance test...\n");for (run = 0; run < PERFORMANCE_RUN_COUNT; ++run){/* Generate test image with random(ish) data: */testImage = (unsigned int *) malloc (fbSize);j = run;for (i = 0; i < (int) (fbSize / sizeof (int)); ++i){testImage[i] = randData[j];j++;if (j >= 17)j = 0;}gettimeofday (&startTime, NULL);memcpy (fb, testImage, fbSize);gettimeofday (&endTime,NULL);long secsDiff = endTime.tv_sec - startTime.tv_sec;results[run] =secsDiff * 1000000 +(endTime.tv_usec - startTime.tv_usec);free (testImage);}average = 0;for (i = 0; i < PERFORMANCE_RUN_COUNT; ++i)average += results[i];average = average / PERFORMANCE_RUN_COUNT;printf (" Average: %llu usecs\n", average);printf (" Bandwidth: %.03f MByte/Sec\n",(fbSize / 1048576.0) / ((double) average / 1000000.0));printf (" Max. FPS: %.03f fps\n\n",1000000.0 / (double) average);/* Clear the framebuffer back to black again: */memset (fb, 0, fbSize);
}int
main (int argc, char **argv)
{const char *devfile = "/dev/fb0";long int screensize = 0;int fbFd = 0;/* Open the file for reading and writing */fbFd = open (devfile, O_RDWR);if (fbFd == -1){perror ("Error: cannot open framebuffer device");exit (1);}//获取finfo信息并显示if (ioctl (fbFd, FBIOGET_FSCREENINFO, &finfo) == -1){perror ("Error reading fixed information");exit (2);}printFixedInfo ();//获取vinfo信息并显示if (ioctl (fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1){perror ("Error reading variable information");exit (3);}printVariableInfo ();/* Figure out the size of the screen in bytes */screensize = finfo.smem_len;/* Map the device to memory */frameBuffer =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,fbFd, 0);if (frameBuffer == MAP_FAILED){perror ("Error: Failed to map framebuffer device to memory");exit (4);}//测试virt fb的性能performSpeedTest (frameBuffer, screensize);printf ("Will draw 3 rectangles on the screen,\n""they should be coloredred, green and blue (in that order).\n");drawRect (vinfo.xres / 8, vinfo.yres / 8,vinfo.xres / 4, vinfo.yres /4, 0xffff0000);drawRect (vinfo.xres * 3 / 8, vinfo.yres * 3 / 8,vinfo.xres / 4, vinfo.yres / 4,0xff00ff00);drawRect (vinfo.xres * 5 / 8, vinfo.yres * 5 / 8,vinfo.xres / 4, vinfo.yres /4, 0xff0000ff);sleep (5);printf (" Done.\n");munmap (frameBuffer, screensize);   //解除内存映射,与mmap对应close (fbFd);return 0;
}

该程序需要在打开FrameBuffer的终端模式下运行,我使用的Ubuntu 12.04,直接按Ctrl + Alt + F1,切换到终端1下,即可运行该程序。程序运行效果如下图所示:

说明一下,在终端模式下,截图软件我用的是fbgrab。

在我的电脑上,该程序在终端打印的信息如下:

Fixed screen info:id: inteldrmfbsmem_start: 0xd0064000smem_len: 8294400type: 0type_aux: 0visual: 2xpanstep: 1ypanstep: 1ywrapstep: 0line_length: 7680mmio_start: 0x0mmio_len: 0accel: 0Variable screen info:xres: 1920yres: 1080xres_virtual: 1920yres_virtual: 1080yoffset: 0xoffset: 0bits_per_pixel: 32grayscale: 0red: offset: 16, length:  8,msb_right:  0green: offset:  8, length:  8, msb_right: 0blue: offset:  0, length:  8, msb_right: 0transp: offset:  0, length:  0, msb_right: 0nonstd: 0activate: 0height: -1width: -1accel_flags: 0x1pixclock: 0left_margin: 0right_margin: 0upper_margin: 0lower_margin: 0hsync_len: 0vsync_len: 0sync: 0vmode: 0Frame Buffer Performance test...Average: 1489 usecsBandwidth: 5312.395 MByte/SecMax.FPS: 671.592 fpsWill draw 3 rectangles on the screen,
they should be colored red, green and blue(in that order).Done.

通过这个测试程序,我们就能理解怎样在Linux用户空间,基于FrameBuffer接口,绘制想要的图形。

Linux FrameBuffer分析之编写基于FrameBuffer接口的应用程序相关推荐

  1. 从入门到入土:[linux实践]-pam|编写基于libpam的用户认证程序|编写基于PAM认证的应用程序|详细说明|实验步骤|实验截图

    写在前面: 此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 编写基于libpam的用户认证程序|编写基于PAM认证的应用 ...

  2. arm裸机与嵌入式linux驱动开发,如何编写基于ARM的裸机程序和基于Linux的驱动程序?...

    在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9Linux内核:3.14 在讲述ADC之前, ...

  3. Linux环境使用命名空间编写一个简单的容器应用程序:namespace,container,cgroups

    目录 使用命名空间编写一个简单的容器应用程序 创建一个子进程– fork vs clone 具有clone(2)的命名空间 简单示例 - CLONE_NEWPID 隔离网络接口 - CLONE_NEW ...

  4. matlab相关性分析频谱_基于Matlab的相关频谱分析程序教程

    基于Matlab的相关频谱分析程序教程 Matlab 信号处理工具箱 谱估计专题 频谱分析 Spectral estimation(谱估计)的目标是基于一个有限的数据集合描述一个信号的功率(在频率上的 ...

  5. usb接口linux系统设计,AUFS 联合文件系统 - 基于USB接口的微型桌面Linux系统设计

    3.4 AUFS 联合文件系统 AUFS( Another UnionFS 的缩写), 是一个与UnionFS 类似的可堆叠联合文件系统,它将多个目录整合成单一的目录,是Linux 文件系统联合挂载的 ...

  6. linux下qt制作日历,基于QT实现的日历程序

    1 概要 本篇设计文档主要讲述了计52班的吴启凌根据小学期第一周李国良老师所教的内容,来实现的程序Calendar的设计思路,架构,以及一些设计细节. Calendar实现了日历的基本功能以及一些附加 ...

  7. linux中用c语言编写一个经纬度转换大地坐标

    在Linux中用C语言编写一个经纬度转换大地坐标的程序,需要用到以下步骤: 包含相关的头文件,例如"math.h". 定义必要的常量和变量. 输入经纬度坐标. 将经纬度转换为弧度. ...

  8. Linux学习笔记(3)- 网络编程以及范例程序

    Linux学习笔记(3)- 网络编程以及范例程序 前言 网络介绍 IP地址的介绍 端口和端口号的介绍 通信流程 socket介绍 TCP介绍 python3编码转换 TCP客户端程序开发流程 多任务版 ...

  9. 基于framebuffer(fb)的驱动分析

    基于framebuffer的驱动分析 framebuffer帧缓冲(简称fb)是linux内核中用代码虚拟出的一个设备,是一个platform类型设备,设备文件位于/dev/fb* 在嵌入式系统中一般 ...

最新文章

  1. 修改单个viewcontroller的状态栏字体颜色
  2. Linux-gate.so.1的含义[ZZ]
  3. Linux 定期删除3天以前的日志文件
  4. 字符串匹配的Boyer-Moore算法
  5. java js引擎,Java8 Nashorn JavaScript引擎
  6. github开源库(三)
  7. 带着问题了解Openstack Neutron安全组
  8. Arc076_E Connected?
  9. 一个真正0基础小白学习前端开发的心路历程
  10. Java 实例 - 查找 List 中的最大最小值
  11. [恢]hdu 2138
  12. python开发k8s管理平台_运维开发和k8s运维如何选择,请各位大神指导一下?
  13. php行为和事件是什么,Yii Framework框架中事件和行为的区别及应用实例分析
  14. 免费文章原创度检测工具
  15. PMBOK(第六版) PMP笔记——《十二》第十二章(项目采购管理)
  16. 网络中的模块化和社区结构(Modularity and community structure in networks)
  17. AI绘图原理:让机器也拥有绘画的灵魂
  18. matplotlib绘图颜色大全
  19. jQuery前端面试题+笔试题+练习题(1)
  20. 《第七周RFID作业》物联112118 林家辉

热门文章

  1. [CF46D]Parking Lot
  2. js 获取浏览器版本信息(全)
  3. 飞剪程序、追剪程序plc程序伺服程序 几年前的飞剪追剪程序,用的都是汇川系列
  4. 全套国潮笔刷,插画绘画,美的方可万物
  5. 15.EasyExcel自定义Convert遇到大坑!!!
  6. Android 页面 滚动
  7. Unity Cinemachine插件学习笔记,结合Timeline实现简单场景动画
  8. 教你三种检测网络故障方法!!!
  9. mac允许允许任何软件执行(任何来源)
  10. CC00037.bigdatajava——|Java方法封装.V19|——|Java.v19|封装实现.v02|