Linux FB 的学习

2023-11-09

linux FB 是CPU 到显示器中的中间人,像一个池子一样。CPU 将操作好的数据项放到池子中,然后再将这些数据显示到屏幕上。

它的好处在于 用户可以将FB看成一个显示内存的映射,当将其映射到用户进程空间是可以直接进行读写操作。操作的方式是通过ioctl的方式,有底层驱动实现。

直接使用命令行操作FB 的方式

  1. 用命令:$ dd if=/dev/zero of=/dev/fb 清空屏幕
  2. 用命令:#dd if=/dev/fb of=fbfile可以将fb中的内容保存下来;
  3. 可以重新写回屏幕: #dd if=fbfile of=/dev/fb

值得一提的是 fbfile 文件大小为6MB。

使用ioctl FBIOGET_FSCREENINFO FBIOGET_VSCREENINFO可以获取到显存大小和实际屏幕的大小。

在fb_fix_screeninfo中有
__u32 smem_len 是这个/dev/fb0的大小,也就是内存大小。
__u32 line_length 是屏幕上一行的点在内存中占有的空间,不是一行上的点数。
在fb_var_screeninfo 中有
__u32 xres ,__u32 yres 是x和y方向的分辨率,就是两个方向上的点数。
__u32 bits_per_pixel 是每一点占有的内存空间。

The mem is :6291456
The line_length is :4096
The xres is :1024
The yres is :768
bits_per_pixel is :32

内存长度恰好为 6291456 / 1024 /1024 = 6。每行占4K的空间。(原文为4M),色彩深度为32bit。屏幕上的点由 1024*768 = 786432个,每个点占32bit,屏幕一共占有内存 32 * 786432 = 25165824 ==》 25165824 / 8 / 1024 /1024 = 3MB。恰好为3MB,但是上面的程序告诉我们有6MB的存储空间。这是因为,多重缓冲技术。显存中有两页的屏幕数据,接替显示,可以实现屏幕抗闪烁等效果。

目前了解了FB,然后可以就在屏幕上进行一个点一个线的绘制。在linux 中一切都是文件,即对屏幕的绘制就是对/dev/fb0的绘制,那么在屏幕上画点的流程就是。

  1. 打开设备

  2. 通过mmap的方式将/dev/fb0映射到用户的进程空间中,然后获取到这个一块内存的大小。
    fbp = mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);

  3. 画点的方式就是 直接赋值来改变屏幕上某点的颜色

    x = 100;
    y = 100;
    location = x * (vinfo.bits_per_pixel / 8) + y  *  finfo.line_length;
    
    
    *(fbp + location) = 100;  /* 蓝色的色深 */  /*直接赋值来改变屏幕上某点的颜色*/
    *(fbp + location + 1) = 15; /* 绿色的色深*/   
    *(fbp + location + 2) = 200; /* 红色的色深*/   
    *(fbp + location + 3) = 0;  /* 是否透明*/  
    

    如果画线的话,就循环画点呗。

完整实例

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

int main(void)
{
    int fp = 0;
    struct fb_var_screeninfo v_info;
    struct fb_fix_screeninfo f_info;
    long s32ScreenSize = 0;
    char * fbp = 0;
    int x = 0;
    int y = 0;
    long s32Location = 0;



    fp = open("/dev/fb0", O_RDWR);

    if(fp < 0 ) {
        perror("open");
        exit(1);
    }

    int s32Ret = -1;

    s32Ret = ioctl(fp, FBIOGET_FSCREENINFO, &f_info);
    if(s32Ret) {
        perror("ioctl");
        goto err;
    }

    s32Ret = ioctl(fp, FBIOGET_VSCREENINFO, &v_info);
    if(s32Ret) {
        perror("ioctl");
        goto err;
    }

    printf("The mem is :%d\n", f_info.smem_len);
    printf("The line_length is :%d\n", f_info.line_length);
    printf("The xres is :%d\n", v_info.xres);
    printf("The yres is :%d\n", v_info.yres);
    printf("bits_per_pixel is :%d\n",v_info.bits_per_pixel);



    printf("long size[%lu] \n", sizeof(long));

    s32ScreenSize = v_info.xres * v_info.yres *  v_info.bits_per_pixel / 8;
    // void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    fbp = (char*) mmap(NULL, s32ScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
    if(fbp == NULL){
        perror("mmap");
        goto err;
    }

    x = 400;
    y = 400;
    s32Location = x * (v_info.bits_per_pixel / 8) + y * f_info.line_length;

    int i = 0;
    for(i = 0; i < 100 ; i++) {
        *(fbp + s32Location + i) = 100;
        *(fbp + s32Location + i + 1) = 15;
        *(fbp + s32Location + i + 2) = 200;
        *(fbp + s32Location + i + 3) = 0;
    }


    munmap(fbp,s32ScreenSize);




    close(fp);

    return 0;
err:
    close(fp);

    exit(1);
    return -1;
}

/dev/fb0入门练习(linux FrameBuffer)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux FB 的学习 的相关文章

  • 将 SQL Server varBinary 数据转换为字符串 C#

    我需要帮助弄清楚如何转换来自SQL服务器表列设置为varBinary 最大 转换为字符串以便将其显示在标签中 这是在C 我正在使用数据读取器 我可以使用以下方式提取数据 var BinaryString reader 1 我知道该列包含之前
  • 如何在 C# 中知道 PID 和 VID 来发现虚拟 COM 端口名称

    如果我知道 PID 和 VID 我会尝试找到查找 COM 端口名称的正确方法 到目前为止 我写了解决方法 但我不相信没有更优雅和正确的方法 顺便说一句 我知道我可以使用 REGEX 编写此代码只是为了测试解决方法 我知道还有很大的改进空间
  • is_integral 与 is_integer:其中之一是多余的吗?

    是积分 http en cppreference com w cpp types is integral and 是整数 http en cppreference com w cpp types numeric limits is inte
  • 如果两个线程同时访问同一个 bool 变量会发生什么?

    我有一个跨平台 C 程序 其中使用 boost 库创建异步计时器 我有一个全局变量 bool receivedInput false 一个线程等待并处理输入 string argStr while 1 getline cin argStr
  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 动态选择和更新 LINQ 结果集中的列值

    我有一个场景 其中存在 LINQ 结果集 我使用了以下查询 var stockDetails from d in db BloodBanks where d bbUserName Session username ToString sele
  • 如何通知父线程所有子线程都已终止?

    我有一个控制台应用程序正在移植到 WPF 该应用程序有 3 个工作线程 在将一些输出结果打印到屏幕上之前 这些线程都连接到主线程 我的理解是 如果我尝试在 WPF 应用程序中执行相同的操作 GUI 将被阻止并且不会响应用户 那么如何通知父线
  • WPF Dispatchertimer 延迟反应/冻结

    在我的 WPF 应用程序中 我使用 3 个不同的 DispatcherTimers 一种是用于显示当前时间 一种是每 5 秒运行一次数据库查询 第三个每 1 秒刷新一次自定义按钮的值 当我的程序运行时 有很多延迟 冻结 例如 时间开始正确计
  • NHibernate IQueryable 集合作为 root 的属性

    我有一个根对象 它有一个集合属性 例如 I have a Shelf object that has Books Now public class Shelf public ICollection
  • 我要恢复我的记忆!我怎样才能真正处理一个控件?

    我正在制作一个应用程序 它创建大量的窗口控件 按钮和标签等 它们都是通过函数动态生成的 我遇到的问题是 当我删除控件并处置它们时 它们不会从内存中删除 void loadALoadOfStuff while tabControlToClea
  • 多维数组和指向指针的指针

    创建多维数组时char a 10 10 根据我的书 它说你必须使用类似于char a 10 将数组传递给函数 为什么必须这样指定长度 您不是只是将双指针传递给 with 并且该双指针不是已经指向分配的内存吗 那么为什么参数不能是char a
  • 如何删除实体框架6中的多对多关系

    如果将项目连接为多对多关系 则从数据库中删除项目时会出现问题 我的数据库看起来像 Project lt JobInProject gt Job ProjectID JobInProjectID JobID ProjectID JobID 主
  • 为什么 httpRuntime targetFramework="4.5" 禁止抓取 .ASPXAUTH cookie?

    当我的 web config 具有以下 httpRuntime 时 我的控制器无法获取 cookie ASPXAUTH 它似乎能够获取任何其他 cookie 无论带或不带句点前缀 如果我删除下面的行 它就可以正常工作
  • 为什么我无法调试动态加载的程序集?

    我正在开发一个 Web API 项目 该项目使用内部模拟框架 允许拦截和修改来自控制器的响应 它使用 MEF 加载包含某些先决条件匹配时执行的代码的程序集 我知道这是正常工作的 因为我可以在响应中看到模拟已被执行 但由于某种原因我无法调试动
  • 类型别名和不完整类型

    我可能已经超出了解决这个本应简单的问题的范围 我在这里开始这个问题 在编译时获取基类的类型 https stackoverflow com questions 17735852 getting type of a base class at
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • 如何在asp.net core 6中注入IConfiguration

    web api 应用程序中不再有 Startup cs 我们以前可以注入IConfiguration进入那个Startup class public class Startup public Startup IConfiguration c
  • 使用非字符串作为字符串(而不是自动使用 ToString)时如何显示错误?

    建议的重复确实是一个类似的问题 然而 答案只涵盖一种选择 禁用 ToString 本身 还有其他可能的解决方案 例如让 Visual Studio 警告我 或者不调用 ToString 仔细阅读那里的答案 他认为is调用 只是解释说没有办法
  • 将多个 Blob 输入传递到 QueueTrigger Azure 函数的最佳方法

    问题 触发后 生成 3 个 XML 文件 完成后将它们通过 ftp 传输到站点 目前的方法 我有一个 HTTP 触发器 Azure 函数 运行时将构造 3 个 XML 文件并将它们保存到 Azure 存储 Blob 容器中 由于有多个输出
  • 返回 ICollection 而不是 List 的真正优势是什么? [复制]

    这个问题在这里已经有答案了 我读过几篇博客文章 提到对于公共 API 我们应该始终返回 ICollection 或 IEnumerable 而不是 List 返回 ICollection 而不是 List 的真正优势是什么 Thanks 复

随机推荐

  • CVE-2017-11882---Microsoft Office数学公式编辑器内存损坏漏洞

    做过不少ctf中的pwn 但还是头一次复现windows的溢出漏洞 目的有二 第一 学会使用windbg 了解它的适用情况和优势 第二 体验在windows下调试溢出漏洞 看看和linux下调试有何不同 0x01 漏洞背景 2017 11
  • Python处理大数据,如何提高处理速度

    Python处理大数据 如何提高处理速度 一 利用大数据分析工具 Dask https dask org Dask简介 Dask支持Pandas的DataFrame和NumpyArray的数据结构 并且既可在本地计算机上运行 也可以扩展到在
  • 《逻辑与计算机设计基础(原书第5版)》——2.10 硬件描述语言—Verilog

    2 10 硬件描述语言 Verilog 由于硬件描述语言用来描述和设计硬件 故在使用该语言编程时 应牢记底层的硬件实现 特别是当你的设计将用来综合时 例如 如果忽略将要生成的硬件 那么你可能会用低效的硬件描述语言设计出一个大且复杂的门级结构
  • Qt小例子学习53 - 使用resizeEvent调整窗口大小时调整Qlabel的图像大小

    Qt小例子学习53 使用resizeEvent调整窗口大小时调整Qlabel的图像大小 testsize h ifndef TESTSIZE H define TESTSIZE H include
  • Qt6+vtk9入门

    目录 1 Qt下载 2 Qt Creator手册 1 edit toolbar 2 双击某控件更改控件名称 3 Qt signal slot Qt 6 vtk9 1 vs2019配置 1 Qt下载 现在下载Qt需要先注册Qt账号 地址htt
  • 【机器学习之向量求导】分子布局 分母布局

    请思考 维度为m的一个向量 对一个标量 的求导 那么结果也是一个m维的向量 这个m维的求导结果排列成的m维向量到底应该是列向量还是行向量 这个问题的答案是 行向量或者列向量皆可 毕竟我们求导的本质只是把标量求导的结果排列起来 至于是按行排列
  • 2016物联网版图:物联网奇点是否已经来临?

    物联网是世界上最让人觉得疑惑的科技趋势吗 一方面 我们了解到它将要成为史诗般的存在 并且所有的预言都说它将带来数百亿互联的设备 创造多达万亿美元的经济价值 但是 在另外一方面 终端用户呈现出的主要感觉是 无聊 现在的IoT感觉就是新互联产品
  • linux之间文件传输(转)

    linux的scp命令 linux 的 scp 命令 可以 在 linux 之间复制 文件 和 目录 scp 命令 scp 可以在 2个 linux 主机间复制文件 命令基本格式 scp 可选参数 file source file targ
  • linux下mysql创建数据库注意

    1 create database a b 为Esc键下面那个键
  • 接口测试用例设计

    接口测试用例设计一 1 接口测试概念 接口测试 测试系统间接口的一种测试 测试的对象主要是接口 主要是测试外部系统与所测系统之间以及内部系统之间的交互点 2 接口测试方法 a 可以通过开发脚本代码进行测试 b 可以通过开源免费的接口调用调试
  • ViewPager2 + Fragment(同一个Fragment)ToolBar显示异常

    一个需求 实现Viewpager2 Fragment实现数据的展示 Viewpager外层不是Activity 而是Fragment 详细说明 在一个Viewpager下 使用的是同一个Fragment 由于每一个Fragment显示的数据
  • 数据结构 —— 顺序表的结构、功能(增删查改)。

    一 概念及结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构 一般情况下采用数据存储 在数组上完成数据的增删查改 顺序表的数据必须从第一个位置开始 连续存储的 顺序表一般可以分为 1 1 静态顺序表 使用定长数组存储元素
  • 苹果笔记本学计算机二级方便吗,你是否真的需要MacBook?

    你们好 这里是Sweekli 为你寻找苹果最新资讯 苹果隐藏技巧 苹果良心APP以及苹果优质配件 如果你需要这些 不妨点个关注 目前 主流的电脑操作系统可能有Windows Mac OS Linux和Chrome OS等 但普通用户在选购时
  • Java的前景如何,好不好自学?

    作为一名拥有十年编程经验的老鸟 我觉得还是很有资格来回答这个问题的 毕竟刚下飞机 首先来回答 Java 的前景如何 在我眼里 Java 绝对是世界第一编程语言啊 PHP 表示不服 那也没办法啊 来看 TIOBE 这个编程语言排行榜吧 上面这
  • java proxy 转包

    java proxy 转包 package org rx socks proxy import io netty channel Channel import io netty channel ChannelFuture import io
  • Spring注解@Lazy

    Spring注解 Lazy 一 Lazy注解 1 Lazy注解作用 lazy 翻译过来是 懒惰的 Lazy 懒加载 该注解用于惰性加载初始化标注的类 方法和参数 在Spring中常用于单实例Bean对象的创建和使用 单实例Bean懒加载 容
  • c编译时的错误:程序中有游离的‘\240’‘\302’‘\XXX 时解决方案

    偶尔从网上看到不错的源码 想研究下 不幸编译时遇到 错误 程序中有游离的 240 302 之类的错误 大量的源码不可能再全部重敲一遍 经过一番研究 终于让我找到简单的解决方案 还是本着让后人少走弯路的想法 分享下 首先 编译器提示的 xxx
  • 给本科实验室的分享PPT-21.7.23

    谢邀 讨论一些学习 兴趣和人生 该分享主要面向实验室的大一 大二同学 时间 2021 7 23
  • Arthas 是Alibaba开源的Java诊断工具

    Arthas 是Alibaba开源的Java诊断工具 深受开发者喜爱 当你遇到以下类似问题而束手无策时 Arthas可以帮助你解决 这个类从哪个 jar 包加载的 为什么会报各种类相关的 Exception 我改的代码为什么没有执行到 难道
  • Linux FB 的学习

    linux FB 是CPU 到显示器中的中间人 像一个池子一样 CPU 将操作好的数据项放到池子中 然后再将这些数据显示到屏幕上 它的好处在于 用户可以将FB看成一个显示内存的映射 当将其映射到用户进程空间是可以直接进行读写操作 操作的方式