framebuffer(帧缓冲)

news2024/9/19 10:42:05

framebuffer

       在Linux系统中,Framebuffer通常是指Framebuffer设备,它是一种特殊的字符设备,在Linux系统中,Framebuffer设备使得程序员可以通过其设定的函数接口直接访问硬件,而不需要通过CPU。

framebuffer的一般操作流程为:

1.打开  (open)
2.获取frame相关信息  (ioctl)
3.映射显存地址  (mmap)
4.向显存写内容(写到映射的用户空间)  
5.解除映射  (munmap)
6.关闭  close(fd);

ioctl()

int ioctl(int fd, unsigned long request, ...);
参数:

fd:操作的文件描述符
request:表示与驱动程序交互的命令,
    用不同的命令控制驱动程序输出我们需要的数据;
    一般使用到的参数:
    FBIOGET_FSCREENINFO:返回与Framebuffer有关的固定的信息,
        比如图形硬件上实际的帧缓存空间的大小、
        能否硬件加速等信息。
    FBIOGET_VSCREENINFO:返回的是与Framebuffer有关的可变信息。
...:表示可变参数 arg,根据 request 命令,
    设备驱动程序返回输出的数据。
    一般使用struct fb_var_screeninfo 来接收参数,对framebuffer进行基础操作用到

   上面几个标注的参数即可

    返回值:

    成功:返回文件描述符
    失败:-1

struct fb_var_screeninfo {
     __u32 xres;         /* visible resolution */这两个字段表示可见分辨率的宽度和高度,                                                                
     __u32 yres;                                //单位是像素。
     __u32 xres_virtual;     /* virtual resolution */
     __u32 yres_virtual;    //这两个字段表示虚拟分辨率的宽度和高度,单位是像素。
                            //虚拟分辨率是指Framebuffer可以支持的最大分辨率。
     __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;__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 */
 };

mmap()

void *mmap(void *addr, size_t length, int prot,
             int flags,int fd, off_t offset);

功能:
创建内存映射
参数:
addr:表示指定映射的內存起始地址,通常设为 NULL,在内存中的映射区中(不是堆)
      表示让系统自动选定地址,并在成功映射后返回该地址;
length:表示将文件中多大的内容映射到内存中;
        一般通过虚拟分辨率(支持最大分辨率)算出:

unsigned long size = info.xres_virtual * info.yres_virtual * info.bits_per_pixel / 8;
 //前面三个变量相乘得到虚拟分辨率所占的比特数(最大分辨率),除8得到字节数

prot:表示映射区域的保护方式,可以为以下 4 种方式的组合
     a. PROT_EXEC 映射区域可被执行
     b. PROT_READ 映射区域可被读出
     c. PROT_WRITE 映射区域可被写入
     d. PROT_NONE 映射区域不能存取    
a. MAP_SHARED  用于创建一个私有的映射,写操作不会立即生效,
            当映射的文件被关闭时,所有未写入的更改会被写入到文件中。
            这种行为类似于文件的临时副本,可以被修改,
            但不会立即影响文件的内容。
            可以安全地修改而不立即影响文件。
 b. MAP_PRIVATE 用于创建一个共享的映射,写操作会立即生效,
            会同步到磁盘,并可以被其他进程看到,
            类似于直接在文件上进行修改    

munmap()

int munmap(void *addr, size_t length)

功能:与mmap函数配套,解除内存映射

参数:

addr: 映射区域的起始地址,即mmap()函数的返回值。

length: 映射区域的大小,以字节为单位。应与mmap()函数中的length参数相同。

返回值:

成功:返回0

失败:返回-1

显示器与显存的关系:

注意:从映射内存中走完显示器整行内容后,下一个元素并不是第二行的第一个元素,而是走完整行显存后,下一个元素才是第二行的第一个元素

 unsigned int * p = (unsigned int *)(p_fd + (y0 * info.xres_virtual + x0) * 4);

示例代码:

1.为什么要使用结构体__color与联合体col?

      便于修改与传参,要对这个颜色(r,g,b)中修改时,明显通过结构体对每一位修改更加直观,更加方便,而联合体的另一个int型变量与结构体(4个char型变量)所占用空间一样,公用一个空间,这时,传入int型l就相当于传入了这个颜色所有的位变量

2.mmap映射出的地址p_fd在函数中使用,是使用全局变量好还是使用传参好?

      全局变量好,因为如果在实际使用中封装函数不希望别的使用者来对这个变量进行修改时(修改后无法找到该映射空间首地址),使用全局变量后,别的使用者无法调用。

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <math.h>

#define pi 3.141592657
struct fb_var_screeninfo info;
unsigned char * p_fd = NULL;

typedef struct __color
{
	unsigned char b;
	unsigned char g;
	unsigned char r;
	unsigned char null;  //暂时不需要透明度
}color;

typedef union 
{
	color rgb;
	unsigned int l;
}col;

int draw_point(int x0, int y0, col c)
{
	if((x0 < 0) || (x0 > info.xres_virtual))
		return -1;
	if((y0 < 0) || (y0 > info.yres_virtual))
		return -1;

	unsigned int * p = (unsigned int *)(p_fd + (y0 * info.xres_virtual + x0) * 4);
	*p = c.l;

	return 0;
}

int draw_h_line(int x0, int y0, int len, col c)
{
	int i = 0;
	for(i = 0; i < len; i++)
	{
		draw_point(x0 + i, y0, c);	
	}

	return 0;
}

int draw_v_line(int x0, int y0, int len, col c)
{
	int i = 0;
	for(i = 0; i < len; i++)
	{
		draw_point(x0, y0 + i, c);	
	}

	return 0;
}

int draw_cicle(int x0, int y0, int r, col c)
{
	float i=0;
	for(i=0;i<360;i+=0.1)
	{
		int x = r * cos(2 * pi * i/360) + x0;
		int y = r * sin(2 * pi * i/360) + y0;
		draw_point(x,y,c);
	}
}

int main(int argc, const char *argv[])
{
	//open
	int fd =  open("/dev/fb0", O_RDWR);
	if(fd < 0)
	{
		perror("open fd failed:");
		return fd;
	}

	//get_screen_info
	int ret = ioctl(fd, FBIOGET_VSCREENINFO, &info);
	if(ret < 0)
	{
		perror("ioctl failed:");
		return ret;
	}
	printf("xres = %d yres = %d\n",
			info.xres, info.yres);
	printf("xres_virtual = %d yres_virtual = %d\n",
			info.xres_virtual, info.yres_virtual);
	printf("bits_per_pixel = %d\n", info.bits_per_pixel);

	//mmap
	unsigned long size = info.xres_virtual * info.yres_virtual * info.bits_per_pixel / 8;
	p_fd = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
	if(NULL == p_fd)
	{
		perror("mmap failed:");
		return -3;
	}

	col c;
	c.rgb.r = 0xff;
	c.rgb.g = 0xff;
	c.rgb.b = 0x0;

	//draw_h_line(100, 100, 200, c);
	draw_cicle(100,200,120,c);

	//munmap
	munmap(p_fd, size);
	//close
	close(fd);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

江协科技51单片机学习- p29 DS18B20温度传感器

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

2-49 基于matlab的表面缺陷的自动分割

基于matlab的表面缺陷的自动分割。基于梯度图操作&#xff0c;对得到的梯度图进行开运算去噪&#xff0c;二值化后经过一定的形态学处理得到缺陷轮廓。通过在两个尺度上同时操作&#xff0c;高尺度的图精细&#xff0c;噪点多&#xff1b;低尺度的图粗糙&#xff0c;但包含的噪…

【人工智能】人工智能概述(二)人工智能的关键技术

文章目录 一. 机器学习与深度学习1. 机器学习2. 深度学习 二. 计算机视觉1. 基本概念和分类2. 未来计算机视觉面临的主要挑战 三. 自然语言处理1. 基本概念与分类2. 自然语言处理面临的四大挑战 四. 知识图谱1. 基本概念2. 应用场景 五. SLAM技术1. 基本概念2. 主要分类 六. 人…

Halcon 感兴趣区域

一 感兴趣区域 机器视觉中感兴趣区域是必不可少的&#xff0c;尤其是Halcon。其目的是将集中处理图像中的特定部分。此方法将区域信息与图像矩阵相结合&#xff0c;只与图像中的某些区域保持关联&#xff0c;减少图像处理的像素。使用ROI的优势&#xff1a;第一&#xff0c;减…

Redis学习[1] ——基本概念和数据类型

Redis学习[1] ——基本概念和数据类型 一、Redis基础概念 1.1 Redis是什么&#xff0c;有什么特点&#xff1f; Redis是一个基于**内存的数据库&#xff0c;因此读写速度非常快**&#xff0c;常用作缓存、消息队列、分布式锁和键值存储数据库。支持多种数据结构&#xff1a;…

网络协议二 : 使用Cisco Packet Traceer工具模拟网络环境,集线器,网桥,交换机,路由器,IP,同一网段

1. 安装 Cisco Packet Tracer baidu 网盘地址&#xff0c;感谢大神分享 安装&#xff0c;破解&#xff0c;中文化&#xff0c;都有说明&#xff0c;建议使用7.x的那个版本&#xff0c;感觉比8.x的翻译要完整一点 https://pan.baidu.com/s/18iWBOfhJJRhqgQqdNQcfMQ?pwddcch#…

【C++】实验七

题目&#xff1a; 1、自己找规律利用数组完成下列数据的输出&#xff1a; 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 思路&#xff1a;数据是斐波那契数列的前20项。该数列特点是除第一第二项以…

公交车客流统计产品介绍

在当今智能科技与交通运输融合的背景下&#xff0c;一款新型公交车客流统计产品应运而生。该系统采用先进的双目客流统计算法&#xff0c;实现多通道视频的客流数据统计&#xff0c;以其高实时性和98%的准确性在复杂环境下准确统计人数。 产品特点 双目客流统计算法 该公交车客…

Vscode报错:line too long (84 > 79 characters)

原因&#xff1a;不允许一行超过79个字母&#xff0c;但是该行代码超出该范围。 参考博客&#xff1a;解决Vs CodeFlake8 报错line too long (108 &#xff1e; 79 characters)Flake8(E501)_flake8 line too long-CSDN博客

Git安装以及配置Gitee秘钥

一、Windows环境GIt安装 1、官网下载git&#xff0c;地址&#xff1a;Git - Downloads 2、安装成功后&#xff0c;点击鼠标右键会有Git GUI Here&#xff08;图形界面&#xff09;和Git Bash Here&#xff08;命令窗口&#xff09; 3、点击Git Bash Here,分别输入以下命令&…

数据库练习4

建库使用库 修改student 表中年龄(sage)字段属性&#xff0c;数据类型由int 改变为smallint 为Course表中Cno 课程号字段设置索引,并查看索引 为SC表建立按学号(sno)和课程号(cno)组合的升序的主键索引&#xff0c;索引名为SC_INDEX 创建一视图 stu info,查询全体学生的姓名&am…

Lingo求解器百度云下载 ling 8.0/lingo 18安装包资源分享

如大家所熟悉的&#xff0c;Lingo是Linear Interaction and General Optimizer的缩写&#xff0c;中文名称为“交互式线性和通用优化求解器”&#xff0c;是一套专门用于求解最优化问题的软件包。 在大部分人认知里&#xff0c;Lingo可用于求解线性规划、二次规划、整数规划、…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.3软件集成

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

交通数据处理-计算途径某些路段的车辆数

根据车辆的运行轨迹&#xff0c;计算先经过某些路段&#xff0c;再经过某些路段的车辆数。 欢迎关注本人公众号--交通数据探索师 如下表&#xff0c; 其中&#xff1a;vehicle: 车辆编号&#xff1b;route: 车辆轨迹。 以第一行为例&#xff0c;车辆car1按顺序经过了路段123…

从0开始搭建vue + flask 旅游景点数据分析系统(三):开发header部分

这一期开始开发header部分&#xff0c;预期实现两个目标&#xff1a; 右侧显示用户名、退出按钮和头像左侧显示系统的访问的路径 1 修改Layout.vue 先修改el-header部分, <el-header class"header"> <!-- <div class"logo">My Ad…

【leetcode 详解】生成特殊数字的最少操作【中等】(C++思路精析)

题目见下&#xff1a; 测试数据: 解题思路笔记&#xff1a; 最初拿到这道题是很蒙的&#xff0c;联想不到什么数据结构的模型&#xff08;肯定是笔者积累太少了&#xff09;&#xff0c;甚至惯性地想怎么实现“删除数字”的操作&#xff1a;在原字符串中抽出一个字符然后将剩…

趋动科技与天数智芯携手构筑全场景高效算力底座

近日&#xff0c;趋动科技与天数智芯正式推出联合解决方案&#xff0c;该方案基于趋动科技OrionX AI算力资源池化软件以及天数智芯通用GPU产品构建AI算力资源池&#xff0c;实现异构算力资源的统一纳管。 经测试&#xff0c;OrionX AI算力资源池化软件与天数智芯通用GPU产品相…

数据结构·红黑树

1. 红黑树的概念 红黑树&#xff0c;是一种搜索二叉树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;可以是Red或Black。通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c;因…

【C++11】C++11新纪元:深入探索右值引用与移动语义

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;位图与布隆过滤器 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C11 &#x1f4d2;1. C11简介…

sentinel的使用以及springcloud整合sentinel

一、为什么要用到sentinel 首先我们要知道的是一个微服务项目如果一个服务挂载掉了&#xff0c;会出现什么情况&#xff0c;是不是回出现一个服务挂载而另一个服务还需要一直调用此服务就很容易导致和它有关联的服务不能被访问到&#xff0c;这也就是我们常常在生活中说到的雪崩…