im6ull学习总结(二)Framebuffer 应用编程

1 LCD操作原理

linux中通过framebuffer驱动程序来控制LCD。framebuffer中包含LCD的参数,大小为LCD分辨率xbpp。framebuffer 是一块内存 内存中保存了一帧图像。
关于图像的帧指的是在图像处理中,一帧(Frame)是指图像序列中的单个静止图像。当连续的图像以每秒多帧的速度播放时,就可以产生动画、视频或电影。每一帧都是由像素组成的二维网格,每个像素都包含颜色和亮度信息。通过在连续的帧之间进行快速切换,人眼会感知到连续的动态效果。因此,一帧是构成动画和视频的基本单元。
LCD的操作过程
1、驱动程序设置好LCD控制器
根据 LCD 的参数设置 LCD 控制器的时序、信号极性;
根据 LCD 分辨率、BPP 分配 Framebuffer。
2、APP 使用 ioctl 获得 LCD 分辨率、BPP
3、APP 通过 mmap 映射 Framebuffer,在 Framebuffer 中写入数据
在这里插入图片描述
假设需要设置 LCD 中坐标(x,y)处像素的颜色,首要要找到这个像素对应的内存,然后根据它的 BPP 值设置颜色。也就是找到内存所对应的地址然后给他赋值。假设 fb_base 是 APP 执行 mmap 后得到的 Framebuffer 地址(首地址)
在这里插入图片描述
计算公式
(x,y)像素起始地址=fb_base+(xres*bpp/8)y + xbpp/8
xres:x方向分辨率bpp每个像素的位数
/8:将位数换算成字节
y y坐标这里从第0行开始所以不用减1
x x坐标
bpp :每个像素的位数bits per pixel
有RGB888 565 555格式
在这里插入图片描述
对于 32BPP,一般只设置其中的低 24 位,高 8 位表示透明度,一般的 LCD都不支持。
对于 24BPP,硬件上为了方便处理,在 Framebuffer 中也是用 32 位来表示,效果跟 32BPP 是一样的。
对于 16BPP,常用的是 RGB565;很少的场合会用到 RGB555,这可以通过ioctl 读取驱动程序中的 RGB 位偏移来确定使用哪一种格式
这里补充一下寻址方式一般为字节寻址也就是说一个地址对应的一个储存单元能储存8位数据。

实验一 并画一条直线

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
static struct fb_var_screeninfo var;
static int  fd_fb;
static unsigned int screen_size;
static unsigned int line_width;
static unsigned int pixel_width;
static unsigned char *fb_base;
static void  lcd_put_pixel(int x, int y,int color)
{
    unsigned char *pen_8 = fb_base+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;
            //printf("*pen_8= %d\n",*pen_8);
            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;
            // printf("*pen_16= %d\n",*pen_16);
			break;
        }
        case 32:
        {
            *pen_32 = color;
            // printf("*pen_32= %d\n",*pen_32);
			break;
        }
    default:
    {
       	printf("can't surport %dbpp\n", var.bits_per_pixel);
        break;
    }
        
    }
}
int main(char argc, char **argv)
{
    int i;
    //这里我先提个问题如何确定设备驱动文件的
    /* 以只读方式打开驱动设备文件 */
    fd_fb = open("/dev/fb0", O_RDWR);
    if(fd_fb<0)
    {
        printf("cannot open /dev/fb0 \n");
        return -1;
    }
    /* fd_fb:是一个打开的 Framebuffer 设备文件的文件描述符。
FBIOGET_VSCREENINFO:是一个常量宏,表示获取可见屏幕信息的操作。
&var:是一个指向 vscreeninfo 结构体的指针,用于接收获取到的可见屏幕信息。 */
   // ioctl成功返回 失败-1
    if (ioctl(fd_fb, FBIOGET_VSCREENINFO,&var))
    {
        printf("can not get var \n");
        return -1;
    }
    /* 一行的字节数 */
    line_width = var.xres *var.bits_per_pixel/8;
    /* bpp转换成字节 */
    pixel_width =  var.bits_per_pixel/8;
    screen_size = var.xres*var.yres*var.bits_per_pixel/8;
    printf("var.bits_per_pixel= %d\n",var.bits_per_pixel);
    /* MAP_SHARED 表示映射区域与其他进程共享。
    0:表示映射区域在文件中的偏移量,此处为从文件开头开始映射。*/
    fb_base=(unsigned char *)mmap(NULL  ,screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
    /* mmap 调用失败,它会返回 MAP_FAILED(通常定义为 (void *)-1) */
    if(fb_base == (unsigned char *) -1)
    {
        printf("can not mmap \n");
        return -1;
    }
    memset(fb_base, 0xff, screen_size);
    for ( i = 0; i < 100; i++)
    {
        lcd_put_pixel(var.xres/2+i,var.yres/2,0xFF0000);
    }
    munmap(fb_base, screen_size);
    close(fd_fb);
    return 0;
}

实验效果
在屏幕中间从左至右画了一条横线
终端打印出:var.bits_per_pixel= 32
这里我有几个问题
1、mmap返回值转换成uchar*类型: 这时注意地址并没有变地址这个指针操作系统是多少位他就永远是多少位,他指向的内容也不会变,只是寻址方式发生变化
在这里插入图片描述
就比如我们看datasheet stm32 的一个寄存器偏移地址为0x00而下一个为0x04 他就是以四个字节递增的。
再比如我们从flash中读取一段数据 要区分半字读还是字读。

2、这引入了第二个问题
在这里插入图片描述
x++后地址偏移的字节数是根据pixel_width决定的 pixel_width = var.bits_per_pixel/8; var.bits_per_pixel 为32位那么一次偏移4个字节刚好32位存储32位数据
在这里插入图片描述
也就是说2进制编码中一个地址存放1位数据0/1 0x1000 到0x1004 则跨了四个字节32位能存储32位数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一篇文章带你轻松入门Python

Python基础 1. Hello World! Python命令行 假设你已经安装好了Python, 那么在命令提示符输入: python 将直接进入python。然后在命令行提示符>>>后面输入: >>>print(Hello World!) 可以看到&#xff0c;随后在屏幕上输出: print是一个常用函数&#xf…

python学习14

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件是一款极其巧妙且具有开创性的工具&#xff0c;它赋予用户细致跟踪和全面分析其网站性能的卓越能力。有了这个非凡的插件&#xff0c;个人可以毫不费力地建立并认真监控他们的Google Analytics目标&#xff0c;从而…

du和df

du 和df 不一致的问题&#xff1a; 情况如下&#xff1a; innode 没有满 同事求助&#xff0c; 他在删掉一个很大的文件后&#xff0c; 磁盘空间依旧没释放。上去一看&#xff0c; 果然 df 看到磁盘空间占用依旧是100%&#xff0c;等等 du 看了一把&#xff0c;磁盘空间剩余很…

低延时视频技术的应用场景和挑战

编者按 无线网络对人们的生活产生了巨大的影响&#xff0c;而5G技术的引入将彻底改变我们与世界互联互通的方式。在5G时代&#xff0c;实现万物互联离不开低延时技术的应用。 LiveVideoStackCon 2023 深圳站邀请到秒点科技的CEO扶凯&#xff0c;为大家分享低延时技术在物联网、…

Impala大数据框架学习网站,大数据技能提升必备利器!

介绍&#xff1a;Impala是Cloudera开发的新型查询系统&#xff0c;它能够对存储在HDFS、HBaseImpala是Cloudera开发的新型查询系统&#xff0c;它能够对存储在HDFS、HBase以及S3上的数据进行快速的交互式SQL查询。此外&#xff0c;Impala与Hive使用了统一的存储系统、同样的元数…

什么是https证书?

HTTPS证书&#xff0c;也称为SSL&#xff08;Secure Sockets Layer&#xff09;证书或TLS&#xff08;Transport Layer Security&#xff09;证书&#xff0c;是一种数字证书&#xff0c;用于在网络上建立安全的加密连接。它的主要目的是确保在互联网上进行的数据传输的安全性和…

提升设计效率:全面了解如何使用Figma插件

Figma组件库包括颜色、字体、图标、按钮、阴影、圆角、间距等。当Figma组件库的样式和Figma组件达到一定数量时&#xff0c;将难以维护&#xff0c;设计和开发的对接成本将大大提高。Figma可以在同一母版下单独设置样式&#xff0c;而不影响与母版之前的关系&#xff0c;这是Sk…

w4操作系统之windows上创建隐藏用户

隐藏用户–在windows上创建隐藏用户 1.首先查看现有哪些用户。&#xff08;通过net user 命令&#xff09; 2.然后创建隐藏用户&#xff08;net user client$ 123 /add&#xff09; 此时出现报错信息。原因是登录用户没权限。需要用管理员的权限 3.用管理员身份运行cmd&am…

AspectJWeaver之Gadget分析

前言&#xff1a; 今天看了下ysoserial的AspectJWeaver方法&#xff0c;分析了下其是如何通过调用SimpleCache$StorableCachingMap来实现写文件&#xff0c;这里把分析的流程写下来&#xff1a; 首先我们要看下其所需要的jar包&#xff1a; <dependencies><dependen…

drf知识-08

Django之了解DRF框架 # 介绍&#xff1a;DRF全称 django rest framework # 背景&#xff1a; 在序列化与反序列化时&#xff0c;虽然操作的数据不尽相同&#xff0c;但是执行的过程却是相似的&#xff0c;也就是说这部分代码是可以复用简化编写的 增&#xff1a;校验请…

基于SSM实现的电动汽车充电网点管理系统

一、系统架构 前端&#xff1a;jsp | jquery | bootstrap | css 后端&#xff1a;spring | springmvc | jdbc 环境&#xff1a;jdk1.8 | mysql 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-登录 03. web端-注册 04. web端-我要充电 05. web端-个人中心-消…

网络编程『简易TCP网络程序』

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; Linux学习之旅、神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f324;️前言&#x1f326;️正文TCP网络程序1.字符串回响1.1.核心功能1.2.程序…

java设计模式学习之【解释器模式】

文章目录 引言解释器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用表达式解析示例代码地址 引言 在我们的日常生活中&#xff0c;语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则&#xff0c;而翻译人员和计算机程序需要理解并遵循这些规则来…

线程基础知识(三)

前言 之前两篇文章介绍了线程的基本概念和锁的基本知识&#xff0c;本文主要是学习同步机制&#xff0c;包括使用synchronized关键字、ReentrantLock等&#xff0c;了解锁的种类&#xff0c;死锁、竞争条件等并发编程中常见的问题。 关键字synchronized synchronied关键字可…

leaflet学习笔记-初始化vue项目(一)

leaflet简介 Leaflet是一款开源的轻量级交互式地图可视化JavaScript库&#xff0c;能够满足大多数开发者的地图可视化需求&#xff0c;其最早的版本大小仅仅38 KB。Leaflet能够在主流的计算机或移动设备上高效运行&#xff0c;其功能可通过插件进行扩展&#xff0c;拥有易于使用…

Java——值得收藏的Java final修饰符总结!!!

Java final修饰符总结 一、final修饰类二、final修饰方法三、final修饰变量 总结 算下刚转Java到现在也有三个多月了&#xff0c;所以打算对Java的知识进行汇总一下&#xff0c;本篇文章介绍一下Java的final修饰符的作用&#xff0c;final表示最后的、最终的含义&#xff0c;fi…

PyTorch 进阶指南,10个必须知道的原则

PyTorch 是一种流行的深度学习框架&#xff0c;它提供了强大的工具和灵活的接口&#xff0c;使得开发者能够搭建和训练各种神经网络模型。这份指南旨在为开发者提供一些有用的原则&#xff0c;以帮助他们在PyTorch中编写高效、可维护和可扩展的代码。 如果你对 Pytorch 还处于…

如何在Mac中设置三指拖移,这里有详细步骤

三指拖移手势允许你选择文本&#xff0c;或通过在触控板上用三指拖动窗口或任何其他元素来移动它。它可以用于快速移动或调整窗口、文件或图像在屏幕上的位置。 然而&#xff0c;这个手势在默认情况下是禁用的&#xff0c;因此在本教程中&#xff0c;我们将向你展示如何在你的…

科荣 AIO ReportServlet 任意文件读取漏洞复现

0x01 产品简介 科荣AIO 企业⼀体化管理解决⽅案 通过ERPERP&#xff08;进销存财务&#xff09;、OAOA&#xff08;办公⾃动化&#xff09;、CRMCRM&#xff08;客⼾关系管理&#xff09;、UDPUDP&#xff08;⾃定义平台&#xff09;&#xff0c;集电⼦商务平台、⽀付平台、ER…