当前位置: 首页 > news >正文

基于x86_64 ubuntu22.04的framebuffer编程

文章目录

  • 前言
  • 一、framebuffer简介
  • 二、framebuffer接口
    • 1.framebuffer设备描述信息
    • 2.framebuffer访问接口
    • 3.查询/设置可更改信息
  • 三、使用步骤


前言

前段时间由于笔记本没有保管好,LCD显示屏压碎了。于是,将笔记本电脑拆开查看LCD型号。在淘宝上下单买了块新的,给老伙计重新装上了。又给笔记本重新装了系统,这个过程甚是艰辛。本来是想装WIN10 X64系统的,制作好U盘启动后程序卡在了win10的启动界面。本来以为可能是内存不够,在网上下单又购买了4G内存条给笔记本换上。装好内存条后,笔记本的运行速度确实有所提升。但是,安装win10 仍然是同样的情况。看来是CPU的性能不够,打算升级CPU。在网上查阅了很多关于升级CPU的帖子,最终结论是主板南桥芯片H55限制了CPU只能选择一代CPU。一代CPU都是双核四线程的,对性能提升应该不是很大。基于此,重新安装回win 7 x64旗舰版。装软件的时候发现,win7 跟 XP一样很多软件都不适用了。而且,还有大量的补丁。最终,选择了给它装上ubuntu 22.04。于是有了本文的硬件基础,本文就是在这台x86_64 ubuntu22.04上做的实验。

一、framebuffer简介

framebuffer是对LCD显示屏的硬件抽象,通过对framebuffer的操作可以直接显示到LCD上。framebuffer是一个字符设备,它向上为用户层提供统一的访问接口,向下屏蔽底层各类硬件显示设备的差异,提高framebuffer设备应用程序的兼容性和可移植性。
framebuffer是一个标准的字符设备,主设备号为29。linux系统最大支持32个framebuffer设备,次设备号一般从0开始,依次为0到31。与其它设备一样,设备节点位于/dev目录下面,一般命名为fbx。例如,/dev/fb0。

二、framebuffer接口

对于framebuffer应用程序开发,不需关心底层的具体实现,只需知道具体访问接口、数据结构以及显示设备的一些必要信息,即可开发应用程序。

1.framebuffer设备描述信息

framebuffer设备信息包括两部分,分别是不可更改和可更改信息。设备信息描述数据结构位于“include/uaip/linux/fb.h”中声明。
不可更改信息描述的是显示设备的固有属性、物理内存地址、物理内存大小等等;对于应用层来说,该部分信息可以用来查询显示设备固有属性信息,对于具体应用过程关联性不大。
struct fb_fix_screeninfo{
char id[16]; /* identification string eg “TT Builtin” /
unsigned long smem_start; /
Start of frame buffer mem /
/
(physical address) /
__u32 smem_len; /
Length of frame buffer mem /
__u32 type; /
see FB_TYPE_* /
__u32 type_aux; /
Interleave for interleaved Planes /
__u32 visual; /
see FB_VISUAL_* /
__u16 xpanstep; /
zero if no hardware panning /
__u16 ypanstep; /
zero if no hardware panning /
__u16 ywrapstep; /
zero if no hardware ywrap /
__u32 line_length; /
length of a line in bytes /
unsigned long mmio_start; /
Start of Memory Mapped I/O /
/
(physical address) /
__u32 mmio_len; /
Length of Memory Mapped I/O /
__u32 accel; /
Indicate to driver which /
/
specific chip/card we have /
__u16 capabilities; /
see FB_CAP_* /
__u16 reserved[2]; /
Reserved for future compatibility */
};

第二部分可更改的信息,涉及显示设备物理分辨率、虚拟分辨率、像素位宽,这部分信息在应用编程需要关注的,以计算显示位置、颜色、映射内存等等。该部分也设计显示设备的固有信息,但应用程序可以通过接口修改。

						struct fb_var_screeninfo{__u32 xres;			/* 可视分辨率(物理分辨率) */__u32 yres;__u32 xres_virtual;	/* 虚拟分辨率 */__u32 yres_virtual;__u32 xoffset;		/* 虚拟分辨率相对可视分配率偏移值 */__u32 yoffset;			__u32 bits_per_pixel;	/* 像素位宽,每个像素用多少未表示 */__u32 grayscale;		/* 灰度等级,0表示彩色,1表示灰度(黑白屏)*//* 缓存RGB位域 */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 *//* 实际显示屏(LCD)参数,根据LCD手册设置,用户层一般不用更改 */__u32 pixclock;			/* 像素时钟 */__u32 left_margin;		/* 显示设备水平方向前肩,单位:时钟 */__u32 right_margin;		/* 显示设备水平方向后肩,单位:时钟 */__u32 upper_margin;		/* 显示设备垂直方式前肩,单位:行 */__u32 lower_margin;		/* 显示设备垂直方向后肩,单位:行 */__u32 hsync_len;		/* 显示设备水平方向有效区域,单位:时钟 */__u32 vsync_len;		/* 显示设备垂直方向有效区域,单位:行 */__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 */}

framebuffer应用程序开发,主要关注的的成员参数是物理分辨率、像素位宽。物理分辨率和像素位宽决定了映射内存的大小,如一个LCD分辨率为1024768、像素位宽为32位;则需要的内存空间大小为:1024768*32/8=3145728字节。

2.framebuffer访问接口

framebuffer设备是一个标准的linux字符设备,可以通过标准虚拟文件接口open/read/write/ioctl/close访问。设备访问分为两部分数据,分别是控制数据流和显示数据流传。对控制数据流通过ioctl结合指定命令实现;对于显示流数据,由于数据量比较大,结合mmap函数,将framebuffer物理内存映射到用户态,直接访问物理内存。
ioctl(fd, cmd, param); /* 文件描述符, 命令字, 参数信息 */

	framebuffer设备ioctl命令位于“include/uapi/linux/fb.h”定义。/* include/uaip/linux/fb.h *//* ioctls0x46 is 'F'			*/#define FBIOGET_VSCREENINFO	0x4600	/* 查询显示设备可更改信息 */#define FBIOPUT_VSCREENINFO	0x4601	/* 设置显示设备可更改信息 */#define FBIOGET_FSCREENINFO	0x4602	/* 查询显示设备不可更改信息 */#define FBIOGETCMAP			0x4604#define FBIOPUTCMAP			0x4605#define FBIOPAN_DISPLAY		0x4606......

3.查询/设置可更改信息

函数原型:
int ioctl(int fd, int cmd, struct fb_var_screeninfo *var);

cmd,命令字:FBIOGET_VSCREENINFO
var,设备可更改信息数据结构
返回,成功返回0,失败返回-1,错误码存于errno中

获取显示设备可更改信息伪代码:

int fb = 0;
struct fb_var_screeninfo var;

fb = open(“/dev/fb0”, O_RDWR);
if (fb < 0)
{
printf(“open fb device failed:%s\n”,strerror(errno));
return -1;
}
if (ioctl(fb, FBIOGET_VSCREENINFO, &var))
{
printf(“read fb device param failed:%s\n”,strerror(errno));
return -1;
}

查询不可更改信息
函数原型:
int ioctl(int fd, int cmd, struct fb_fix_screeninfo *var);

cmd,命令字:FBIOGET_FSCREENINFO
var,设备不可更改信息数据结构
返回,成功返回0,失败返回-1,错误码存于errno中

获取显示设备不可更改信息伪代码:
int fb = 0;
struct fb_fix_screeninfo fix;

fb = open(“/dev/fb0”, O_RDWR);
if (fb < 0)
{
printf(“open fb device failed:%s\n”,strerror(errno));
return -1;
}
if (ioctl(fb, FBIOGET_FSCREENINFO, &fix))
{
printf(“read fb device param failed:%s\n”,strerror(errno));
return -1;
}

三、使用步骤

应用程序访问一个framebuffer设备的的总体流程如下图。
在这里插入图片描述
实例:
获取framebuffer设备信息
“红—绿—蓝” 1秒周期循环刷新输出

##include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fb.h>

struct _fb_info
{
int fd; /* framebuffer 文件描述符 /
uint8_t pbuf; / 映射内存 /
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;/
framebuffer设备信息
/
};

struct _fb_info fb_app = {0};

/* 画点函数 */
static void draw_pixel(struct _fb_info *fb, int x, int y, uint32_t color)
{
uint8_t *poffset_buf = NULL;

poffset_buf = fb->pbuf + (x*fb->var.bits_per_pixel/8) + (y*fb->var.xres*fb->var.bits_per_pixel/8);	/* 计算内存偏移地址 */
*(uint32_t*)poffset_buf = color;	/* ARGB32格式 */

}

/* 全屏画点函数 */
static void fill_pixel(struct _fb_info *fb, uint32_t color)
{
int i, j;

for (i=0; i<fb->var.xres; i ++) 
{for (j=0; j<fb->var.yres; j ++) {draw_pixel(fb, i, j, color);}
}

}

int main(int argc, char *argv[])
{
int ret = 0;
int mem_size = 0;

if (argc < 2)
{printf("parameter invalid\n");return -1;
}fb_app.fd = open(argv[1], O_RDWR);
if (fb_app.fd < 0)
{printf("open device [%s] failed:%s\n", argv[1], strerror(errno));return -1;
}
printf("framebuffer device:%s\n", argv[1]);/* 读取不可更改信息 */
ret = ioctl(fb_app.fd, FBIOGET_FSCREENINFO, &fb_app.fix);    
if (ret < 0)
{printf("read fb device fscreeninfo failed:%s\n", strerror(errno));close(fb_app.fd);return -1;
}
printf("device id:%s\n", fb_app.fix.id);
printf("smem_start:0x%x, smem_len:%u\n", fb_app.fix.smem_start, fb_app.fix.smem_len);    /* 读取可更改信息 */
ret = ioctl(fb_app.fd, FBIOGET_VSCREENINFO, &fb_app.var);
if (ret < 0)
{printf("read fb device vscreeninfo failed:%s\n", strerror(errno));close(fb_app.fd);return -1;
}
printf("visible resolution:%d*%d\n", fb_app.var.xres, fb_app.var.yres);
printf("virtual resolution:%d*%d\n", fb_app.var.xres_virtual, fb_app.var.yres_virtual);
printf("pixel bits wide:%d\n", fb_app.var.bits_per_pixel);
printf("grayscale:%d\n", fb_app.var.grayscale);mem_size = fb_app.var.xres * fb_app.var.yres * fb_app.var.bits_per_pixel / 8;	/* 计算内存 */
fb_app.pbuf = (uint8_t *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fb_app.fd, 0);
if (fb_app.pbuf == NULL)
{printf("fb device mmap failed:%s\n", strerror(errno));close(fb_app.fd);return -1;
}
memset(fb_app.pbuf, 0, mem_size);	/* 清屏操作(黑屏)*/
for (;;)
{fill_pixel(&fb_app, 0xffff0000);/* 红 */sleep(1);fill_pixel(&fb_app, 0xff00ff00);/* 绿 */sleep(1);fill_pixel(&fb_app, 0xff0000ff);/* 蓝 */sleep(1);
}
munmap(fb_app.pbuf, mem_size);
close(fb_app.fd);return 0;	

}

相关文章:

基于x86_64 ubuntu22.04的framebuffer编程

文章目录 前言一、framebuffer简介二、framebuffer接口1.framebuffer设备描述信息2.framebuffer访问接口3.查询/设置可更改信息 三、使用步骤 前言 前段时间由于笔记本没有保管好&#xff0c;LCD显示屏压碎了。于是&#xff0c;将笔记本电脑拆开查看LCD型号。在淘宝上下单买了…...

解密回文--栈

“ xyzyx ”是一个回文字符串&#xff0c;所谓回文字符 串就是指正读反读均相同的字符序列&#xff0c;如“席主席”、“记书记”、“ aha ”和“ ahaha ”均是回 文&#xff0c;但“ ahah ”不是回文。通过栈这个数据结构我们将很容易判断一个字符串是否为回文。 首先我们需…...

Mysql主从服务安装配置

1.下载地址 MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/ 2.安装配置 1.下载解压后&#xff0c;拷贝一份作为slave的安装目录 3.配置my.ini 由于下载mysql8版本&#xff0c;解压后&#xff0c;没有相关的my…...

双向BFS

1034 Number Game 分数 35 作者 陈越 单位 浙江大学 A number game is to start from a given number A, and to reach the destination number B by a sequence of operations. For the current number X, there are 3 types of operations: XX1 XX−1 XXN Your job is to f…...

数据艺术:精通数据可视化的关键步骤

数据可视化是将复杂数据转化为易于理解的图表和图形的过程&#xff0c;帮助我们发现趋势、关联和模式。同时数据可视化也是数字孪生的基础&#xff0c;本文小编带大家用最简单的话语为大家讲解怎么制作一个数据可视化大屏&#xff0c;接下来跟随小编的思路走起来~ 1.数据收集和…...

MySQL 是如何实现事务的四大特性的?

分析&回答 如果你不知道事务更不知道四大特性请先看看&#xff1a;说说什么是事务 原子性 语句要么都执行&#xff0c;要么都不执行&#xff0c;是事务最核心的特性&#xff0c;事务本身来说就是以原子性来定义的&#xff0c;实现主要是基于undo log undo log&#xff…...

python实现zscore归一化和minmax标准化

zscore归一化&#xff1a; minmax from sklearn import preprocessing from sklearn.preprocessing import StandardScaler import numpy as np# 数据 x np.array([[1.,-1.,2.],[2.,0.,0.],[0.,1.,-1.]]) print(----------------minmaxscaler标准化-------------) # 调用minma…...

架构师成长之路Redis第三篇|Redis key过期清除策略

Eviction policies maxmemory 100mb 当我们设置的内存达到指定的内存量时,清除策略的配置方式决定了默认行为。Redis可以为可能导致使用更多内存的命令返回错误,也可以在每次添加新数据时清除一些旧数据以返回到指定的限制。 当达到最大内存限制时,Redis所遵循的确切行为是…...

C++智能指针之weak_ptr(保姆级教学)

目录 C智能指针之weak_ptr 概述 作用 本文涉及的所有程序 使用说明 weak_ptr的常规操作 lock(); use_count(); expired(); reset(); shared_ptr & weak_ptr 尺寸 智能指针结构框架 常见使用问题 shared_ptr多次引用同一数据&#xff0c;会导致两次释放同一内…...

ElementUI浅尝辄止18:Avatar 头像

用图标、图片或者字符的形式展示用户或事物信息。 常用于管理系统或web网站的用户头像&#xff0c;在用户账户模块更换头像操作也能看到关于Avatar组件的应用。 1.如何使用&#xff1f; 通过 shape 和 size 设置头像的形状和大小。 <template><el-row class"de…...

1688API技术解析,实现按图搜索1688商品(拍立淘)

一种可能的解决方案是使用图像识别和相似度匹配的算法。您可以通过将输入的图片与1688上的商品图片进行比对&#xff0c;找出最相似的商品。这涉及到图像特征提取、相似度计算以及数据库匹配等技术。您可以使用开源的图像处理库&#xff08;如OpenCV&#xff09;来进行图像处理…...

【面试经典150题】买卖股票的最佳时机

题目链接 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…...

selenium可以编写自动化测试脚本吗?

Selenium可以用于编写自动化测试脚本&#xff0c;它提供了许多工具和API&#xff0c;可以与浏览器交互&#xff0c;模拟用户操作&#xff0c;检查网页的各个方面。下面是一些步骤&#xff0c;可以帮助你编写Selenium自动化测试脚本。 1、安装Selenium库和浏览器驱动程序 首先…...

CXL.mem M2S Message 释义

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…...

使用boost::geometry::union_ 合并边界(内、外):方案二

使用boost::geometry::union_ 合并边界&#xff08;内、外&#xff09;&#xff1a;方案二 typedef boost::geometry::model::d2::point_xy<double> boost_point; typedef boost::geometry::model::polygon<boost_point> boost_Polygon;struct Point {float x;floa…...

ICCV 2023 | 小鹏汽车纽约石溪:局部上下文感知主动域自适应LADA

摘要 主动域自适应&#xff08;ADA&#xff09;通过查询少量选定的目标域样本的标签&#xff0c;以帮助模型从源域迁移到目标域。查询数据的局部上下文信息非常重要&#xff0c;特别是在域间差异较大的情况下&#xff0c;然而现有的ADA方法尚未充分探索这一点。在本文中&#…...

stable diffusion实践操作-黑白稿线稿上色

系列文章目录 本文专门开一节【黑白稿线稿上色】写相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 文章目录 系列文章目录前言一、操作步骤1. 找到黑白线稿图 总结 前言 本章主要介绍黑白稿线稿上色&#xff0c;这是通过Cont…...

Python学习教程:集合操作的详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 Python中有两种可以遍历的容器类型&#xff1a; 序列类型&#xff1a;包含字符串、列表、元祖 序列类型是线性表&#xff0c;就像数组一样&#xff0c;是在内存中开辟一块连续空间&#xff0c;连续存储的&#xff0c; 那么查找…...

球球的排列

题目传送门 引 计数DP,好像特别经典&#xff0c;有两种做法&#xff0c;我只会 O ( n 3 ) O(n^3) O(n3),有 O ( n 2 ) O(n^2) O(n2)的 解法 首先&#xff0c; 若 x y p 2 且 x z q 2 , 则 y z ( p q x ) 2 若xyp^2且xzq^2,则yz(\frac{pq}{x} )^2 若xyp2且xzq2,则yz(xpq…...

1783_CMD启动MATLAB同时执行一个脚本

全部学习汇总&#xff1a; GitHub - GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...