Framebuffer 应用编程

Frame的意思是帧,buffer的意思是缓冲区。Framebuffer就是一块内存(硬件设备),里面保存着一帧图像。

ioctl()函数解析

ioctl()函数非常强大。不同的驱动程序内部会实现不同的 ioctl() ,可以使用各种 ioctl() 跟驱动程序交互:可以传数据给驱动程序,也可以从驱

动程序中读出数据。

头文件:

#include <sys/ioctl.h>

函数原型:

int ioctl(int fd, unsigned long request, ...);

函数说明:

① fd 表示文件描述符;

② request 表示与驱动程序交互的命令, 用不同的命令控制驱动程序输出我们需要的数据

③ … 表示可变参数 arg, 根据 request 命令,设备驱动程序返回输出的数据。

④ 返回值: 打开成功返回0,失败将返回-1

实现步骤

1.获取framebuffer描述符

fd_fb = open("/dev/fb0", O_RDWR);  //可读可写
if(fd_fb == -1) {
printf("can not open /dev/fb0\n");
return -1;
}

2.获取屏幕可变参数

if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)) { //结构体名不是地址,需要取地址。FBIOGET_VSCREENINFO是获取可变参数(fb.h)
printf("can not get var\n");
return -1;
}

3.计算framebuffer空间大小

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; //单位:字节
fb_base = (unsigned char*)mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if(fb_base == (unsigned char*)-1) {
printf("can not mmap\n");
return -1;
}

4.不同的RGB格式转换

switch(var.bits_per_pixel)
{
case 8:
{
/*代码*/
break;
}
case 16:
{
/* 32位转换为RGB565 */
red = (color >> 16) & 0xff; //保留17-24位
green = (color >> 8) & 0xff; //保留8-16位
blue = (color >> 0) & 0xff; //保留0-8位
color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3); //组合为16bit
*add_16 = color; //像素点对应的地址空间赋值
break;
}
case 32:
{
*add_32 = color;
break;
}
default:
printf("can't surport %dbpp\n", var.bits_per_pixel);
break;
}

完整程序如下:

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h> int fd_fb; //文件描述符
int screen_size; //屏幕总字节数(framebuffer的大小)
struct fb_var_screeninfo var;
unsigned char *fb_base;
unsigned int line_width; //行字节
unsigned int pixel_width; //像素字节 void lcd_put_pixel(int x, int y, unsigned int color) {
unsigned char *add_8 = fb_base + y*line_width + x*pixel_width; //像素点对应的内存地址
unsigned short *add_16;
unsigned int *add_32; unsigned int red, green, blue; add_16 = (unsigned short*)add_8; //8位转换为16位
add_32 = (unsigned int*) add_8; switch(var.bits_per_pixel)
{
case 8:
{
/*代码*/
break;
}
case 16:
{
/* 32位转换为RGB565 */
red = (color >> 16) & 0xff; //保留17-24位
green = (color >> 8) & 0xff; //保留8-16位
blue = (color >> 0) & 0xff; //保留0-8位
color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3); //组合为16bit
*add_16 = color; //像素点对应的地址空间赋值
break;
}
case 32:
{
*add_32 = color;
break;
}
default:
printf("can't surport %dbpp\n", var.bits_per_pixel);
break;
} } int main(int argc, char **argv)
{
int i; /* 1.获取framebuffer描述符 */
fd_fb = open("/dev/fb0", O_RDWR); //可读可写
if(fd_fb == -1) {
printf("can not open /dev/fb0\n");
return -1;
} /* 2.获取屏幕可变参数 */
if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)) { //结构体名不是地址,需要取地址
printf("can not get var\n");
return -1;
} /* 3.计算framebuffer空间大小 **/
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; //单位:字节
fb_base = (unsigned char*)mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if(fb_base == (unsigned char*)-1) {
printf("can not mmap\n");
return -1;
} /* 清屏: 全部设为白色 */
memset(fb_base, 0xff, screen_size); /* 随便设置出100个为蓝色 */
for (i = 0; i < 100; i++)
lcd_put_pixel(var.xres/2+i, var.yres/2, 0x0000FF); munmap(fb_base , screen_size);
close(fd_fb); return 0;
}

嵌入式Linux—Framebuffer应用编程的更多相关文章

  1. 嵌入式linux的网络编程(1)--TCP/IP协议概述

    嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...

  2. 嵌入式Linux下Camera编程--V4L2【转】

    转自:http://blog.csdn.net/fwqlzz/article/details/51126653 版权声明:本文为博主原创文章,未经博主允许不得转载. USB video class(又 ...

  3. 嵌入式Linux串口编程简介

    文章目录 简介 用到的API函数 代码 简介 嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的.嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大 ...

  4. 常见的嵌入式linux学习和如何选择ARM芯片问答

    常见的ARM嵌入式学习问答,设计者和学习者最关心的11个问题: 1.          ARM嵌入式是学习硬件好还是学习软件好? 2.          嵌入式软件和硬件,哪一种职位待遇更高?或者说, ...

  5. 嵌入式linux多进程编程

    嵌入式linux多进程编程 在主程序显示文本菜单.提供例如以下服务.要求每一个服务都通过生成子进程来提供. 服务包含:日历信息显示,日期信息显示,推断闰年服务,文件复制功能,数字排序功能.退出功能. ...

  6. 从裸机编程到嵌入式Linux编程思想的转变------分而治之:驱动和应用程序

    笔者学习嵌入式Linux也有一段时间了,很奇怪的是很多书讲驱动编程方面的知识,也有很多书将ARM9方面的知识,但是从以前51形式的(对寄存器直接操作,初始化芯片的功能模块)编程方法,和思维模式,变换为 ...

  7. 《嵌入式linux应用程序开发标准教程》笔记——6.文件IO编程

    前段时间看APUE,确实比较详细,不过过于详细了,当成工具书倒是比较合适,还是读一读这种培训机构的书籍,进度会比较快,遇到问题时再回去翻翻APUE,这样的效率可能更高一些. <嵌入式linux应 ...

  8. Yocto开发笔记之《嵌入式linux libcurl编程》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  9. Linux Framebuffer驱动剖析之一—软件需求

    嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT两方面的原创技术分享,稍后会发布嵌入式企鹅圈的2 ...

  10. 嵌入式linux GUI--DirectFB + GTK至尊秘笈

    前言 数年前,曾经开发过一个嵌入式的产品,如今市场依然存在,但由于电子产品的升级换代很快,许多元器件都采购不到了,为了延续产品的生命周期,计划在linux平台上开发新的版本.而在linux上的GUI上 ...

随机推荐

  1. 【初赛】CSP 2020 第一轮(初赛)模拟记录

    感觉初赛不过关,洛谷上找了一套没做过的来练习. 顺便写了详细的题解. 试题用时:1h 单项选择: 第 1 题 十进制数 114 的相反数的 8 位二进制补码是: A.10001110 B.100011 ...

  2. 12 张图看懂 CPU 缓存一致性与 MESI 协议,真的一致吗?

    本文已收录到  GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star.技术和职场问题,请关注公众号 [彭旭锐] 进 Android 面试交流群. 前言 大家好 ...

  3. OSI传输层TCP与UDP协议、应用层简介、socket模块介绍及代码优化、半连接池的概念

    目录 传输层之TCP与UDP协议 应用层 socket模块 socket基本使用 代码优化 半连接池的概念 传输层之TCP与UDP协议 TCP与UDP都是用来规定通信方式的 通信的时候可以随心所欲的聊 ...

  4. updog:一款局域网传输文件的软件

    前言 不知道你是否有过这样 的需求,在局域网传输文件,苦于没有好的软件支持,或者只能单向传输,updog可以完全解决这种问题 安装 pip3 install updog updog是python中的一 ...

  5. 批量删除多个相同格式内容的Excel表格的列

    Sub Del_Col()Application.DisplayAlerts = FalseDim myFiles As StringDim myExcels As StringWith Applic ...

  6. [.NET学习] EFCore学习之旅 -1

    1.创建项目 这里我们先新建一个控制台项目:"jyq.EFCore.Learn",框架基于.NET6 2.安装 Neget包 Install-Package Microsoft.E ...

  7. 学生管理系统Python

    student1=[ {1:'lucy','age':17,'sex':'n','Pnum':1111111}, {2:'tom','age':17,'sex':'m','Pnum':2222222} ...

  8. 【微服务架构设计实施】第一部分:架构篇-1:微服务架构与Spring Cloud介绍

    〇.概述 一.微服务架构与Spring Cloud (一)概念 不同说法:细粒度的.清凉组件化的小型SOA(面向服务架构) 统一说法:小型应用程序(服务组件),使用轻量级设计方法和HTTP协议通信 理 ...

  9. tcp/udp 协议特性和三次握手

    一.TCP/UDP协议特性1)TCP特性:工作在传输层.建立连接.可靠的.错误检查 2)UDP特性:工作在传输层.不需要连接.不可靠的.有限的错误检查.传输性能高 2.控制位及确认号解释 控制位:由6 ...

  10. CH392/CH395常见问题解决方法指南

    CH395 问题 1: CH395 初始化失败.解答: 1.首先检查"check_exist"命令,正常情况下 CH395 会将该命令的输入值按位取反后输出,若该命令不正常,则说明 ...