Linux下的Framebuffer编程
文章目录
- 前言
- 一、LCD操作原理
- 二、代码解析及编写程序的步骤
- 0.定义各类参数
- 1.打开LCD设备节点
- 2.获取触摸屏数据
- 3.mmap映射Framebuffer,在Framebuffer中写入数据
- 三、LCD操作函数解析
- 1.描点函数
- 2.显示字符函数
- 总结
前言
本篇文章将会介绍Linux下的Framebuffer编程,这里将会引用到百问网韦东山老师讲的一些知识。
一、LCD操作原理
在Linux系统中通过Framebuffer驱动程序来控制LCD。Frame是帧的意思,buffer是缓冲的意思,这意味着Framebuffer就是一块内存,里面保存着一帧图像。Framebuffer中保存着一帧图像的每一个像素颜色值,假设LCD的分辨率是1024x768,每一个像素的颜色用32位来表示,那么Framebuffer的大小就是:1024x768x32/8=3145728字节。
二、代码解析及编写程序的步骤
0.定义各类参数
下面这些参数后面我们会一 一介绍。
int fd_fb;
struct fb_var_screeninfo var; /* Current var */
int screen_size;
unsigned char *fbmem;
unsigned int line_width;
unsigned int pixel_width;
1.打开LCD设备节点
这些的fd_fb就是打开LCD设备返回的文件句柄。
/dev/fb0 :LCD设备节点(根据自己板子上面的节点填写)
fd_fb = open("/dev/fb0", O_RDWR);if (fd_fb < 0){printf("can't open /dev/fb0\n");return -1;}
2.获取触摸屏数据
使用ioctl获取LCD的一些参数信息,并将这些参数的信息放入var结构体中。
if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)){printf("can't get var\n");return -1;}
var结构体解析:
这个结构体里面保存了LCD的相关信息,比如xres和yres就是代表了x方向的分辨率和y方向的分辨率。
大家的手机都有分辨率,最常见的就是1080×1920了。对应到xres和yres就是xres=1080,yres=1920。
大家只需要知道var这个结构体是用来保存ioctl获取到的LCD的参数信息即可。
bits_per_pixel:每一个像素的颜色用多少位表示
struct fb_var_screeninfo {__u32 xres; /* visible resolution */__u32 yres;__u32 xres_virtual; /* virtual resolution */__u32 yres_virtual;__u32 xoffset; /* offset from virtual to visible */__u32 yoffset; /* resolution */__u32 bits_per_pixel; /* guess what */__u32 grayscale; /* 0 = color, 1 = grayscale, *//* >1 = FOURCC */struct fb_bitfield red; /* bitfield in fb mem if true color, */struct fb_bitfield green; /* else only length is significant */struct fb_bitfield blue;struct fb_bitfield transp; /* transparency */ __u32 nonstd; /* != 0 Non standard pixel format */__u32 activate; /* see FB_ACTIVATE_* */__u32 height; /* height of picture in mm */__u32 width; /* width of picture in mm */__u32 accel_flags; /* (OBSOLETE) see fb_info.flags *//* Timing: All values in pixclocks, except pixclock (of course) */__u32 pixclock; /* pixel clock in ps (pico seconds) */__u32 left_margin; /* time from sync to picture */__u32 right_margin; /* time from picture to sync */__u32 upper_margin; /* time from sync to picture */__u32 lower_margin;__u32 hsync_len; /* length of horizontal sync */__u32 vsync_len; /* length of vertical sync */__u32 sync; /* see FB_SYNC_* */__u32 vmode; /* see FB_VMODE_* */__u32 rotate; /* angle we rotate counter clockwise */__u32 colorspace; /* colorspace for FOURCC-based modes */__u32 reserved[4]; /* Reserved for future compatibility */
};
3.mmap映射Framebuffer,在Framebuffer中写入数据
line_width:var.xres * var.bits_per_pixel代表每一行有多少个像素
/8就代表了每一行有多少个字节
pixel_width :每一个像素多少个字节
screen_size :计算出整个屏幕所占字节的大小
fbmem :Framebuffer是存在于驱动程序当中的,在应用程序中不可直接使用,需要使用mmap将驱动程序的内存映射到应用程序中才可进行操作。
line_width = var.xres * var.bits_per_pixel / 8;pixel_width = var.bits_per_pixel / 8;screen_size = var.xres * var.yres * var.bits_per_pixel / 8;fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);if (fbmem == (unsigned char *)-1){printf("can't mmap\n");return -1;}
三、LCD操作函数解析
1.描点函数
pen_8 ,pen_16,pen_32参数代表的是起笔点,因为我使用的LCD每个像素是8位的,所以我这里只需要计算pen_8 即可,其他两个只需要进行一次转换即可。
pen_8 的计算
void lcd_put_pixel(int x, int y, unsigned int color)
{unsigned char *pen_8 = fbmem+y*line_width+x*pixel_width;unsigned short *pen_16; unsigned int *pen_32; unsigned int red, green, blue; pen_16 = (unsigned short *)pen_8;pen_32 = (unsigned int *)pen_8;switch (var.bits_per_pixel){case 8:{*pen_8 = color;break;}case 16:{/* 565 */red = (color >> 16) & 0xff;green = (color >> 8) & 0xff;blue = (color >> 0) & 0xff;color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);*pen_16 = color;break;}case 32:{*pen_32 = color;break;}default:{printf("can't surport %dbpp\n", var.bits_per_pixel);break;}}
}
2.显示字符函数
void lcd_put_ascii(int x, int y, unsigned char c, unsigned int color)
{unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];int i, b;unsigned char byte;for (i = 0; i < 16; i++){byte = dots[i];for (b = 7; b >= 0; b--){if (byte & (1<<b)){/* show */lcd_put_pixel(x+7-b, y+i, color); /* 白 */}else{/* hide */lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */}}}
}
总结
本篇文章就介绍到这里,Framebuffer编程的编程其实并不算很难,大家只要理清楚这些参数即可。具体的代码请参考百问网,这里我只做重要部分介绍。
Linux下的Framebuffer编程相关推荐
- linux c语言工具,Linux下C语言编程环境的工具.doc
Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 要想在Linux下进行C语言编程,首先得搭建好一个编程环境.这里分别说明一下几个非常有用的软件包. ...
- Linux下C语言编程-进程的创建
Linux下C语言编程-进程的创建 作者:hoyt 1.进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢?在现代的操作 ...
- linux下的c编程
vi编译器简介 vi的三种模式,分别为命令行模式,插入模式以及底行模式,这里游客去看,这里提供好几个小技巧:G表示移动到文件末尾nG表示移动到第几行 gcc优化选项 gcc可以对代码进行优化,他可以通 ...
- linux fb应用例子,Linux下利用framebuffer画点的程序小例子
Linux下利用framebuffer画点的程序小例子: /* * ================================================================== ...
- linux+下c语言编程项目,精通UNIX下C语言编程与项目实践
cc -I //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编译 ...
- 您知道Linux下C语言编程的一些注意事项吗_教育中国
您知道Linux下C语言编程的一些注意事项吗_教育中国 云风的 BLOG: 一个 C 接口设计的问题 一个 C 接口设计的问题 C 语言在本质上,参数传递都是值传递.不像 Pascal 和 C++ 可 ...
- Linux下TCP网络编程-创建服务器与客户端
一.前言 互联网概念诞生于20世纪60年代末,从9几年中国接入互联网开始到现在,生活的每个角落都能看到网络的使用.现在物联网时代.共享经济的到来,生活中不仅仅电脑.手机可以接入网络,身边的各个设备也能 ...
- c 调用 linux驱动程序,Linux下的C编程实战(五)――驱动程序设计
Linux下的C编程实战(五) ――驱动程序设计 1.引言 设备驱动程序是操作系统内核和机器硬件之间的接口,它为应用程序屏蔽硬件的细节,一般来说,Linux的设备驱动程序需要完成如下功能: (1)初始 ...
- linux c语言 ppt,Linux下C语言编程.ppt
Linux下C语言编程 Linux中C语言的重要性 Linux和C天生有不解之缘. Linux操作系统的内核主要是用C写的,另外Linux下的很多软件也是用C写的,特别是一些著名的服务软件,比如MyS ...
最新文章
- R语言ggplot2可视化:绘制堆叠的密度图(Stacked Area Chart)
- Android Studio开发第二篇创建新项目
- http的302,303和307
- Spark SQL(一)之简介
- android 动态生成fragment,Android动态加载fragment(fragment复用)
- LeetCode:递归思想的延伸,从斐波那契数列到爬楼梯模型
- centos下安装CH341驱动
- MFC中资源视图中对话框大小和实际像素尺寸显示问题
- ping服务器响应39ms,美国服务器的ping值多少网速才算快?
- uni-app Image组件在加载图片发生错误时,显示默认图片
- Oracle查询列重命名问题
- 玩吧!北京!招人!Java!
- 黑苹果相关(说好的不折腾)
- 在pc端上操作手机工具分享
- 机器学习:分类模型大全
- SpringBoot+MyBatisPlus+Thymeleaf+AdminLTE增删改查实战
- STM32移植到GD32的问题---20170923
- elementplus 上传文件
- 谁要GMAIL和Orkut的邀请?
- Linux列出磁盘信息