Framebuffer应用编程

devtools/2025/3/20 15:07:02/

1. 引言

Framebuffer 是 Linux 下用于直接操作屏幕显示的机制,开发者可以通过访问 /dev/fb0 设备来控制显示内容。在嵌入式开发或图形驱动开发中,Framebuffer 提供了一种简单而高效的方式进行图像渲染。本篇文章基于 lcd_put_pixel 函数的示例代码,介绍 Framebuffer 的基本操作,包括设备初始化、内存映射、像素绘制和清屏等功能。

2. Framebuffer 设备概述

Framebuffer(帧缓冲区)是操作系统提供的一块内存映射区域,直接对应显示设备的像素数据。用户可以通过 mmap 将该区域映射到用户空间,进而操作屏幕上的像素点。常见的 Framebuffer 设备文件是 /dev/fb0,不同的显示设备可能对应 /dev/fb1/dev/fb2 等。

3. Framebuffer 设备的初始化

在使用 Framebuffer 之前,首先需要打开设备文件并获取屏幕的基本信息。以下代码实现了 Framebuffer 的初始化:

fd_fb = open("/dev/fb0", O_RDWR);
if (fd_fb < 0) {printf("can't open /dev/fb0\n");return -1;
}if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)) {printf("can't get var\n");return -1;
}

这里使用 open 函数获取 Framebuffer 设备的文件描述符 fd_fb,然后通过 ioctl 调用 FBIOGET_VSCREENINFO 获取屏幕的分辨率、像素位深度等信息。

4. 内存映射

Framebuffer 的核心操作是使用 mmap 将显存映射到用户空间,从而可以直接操作像素数据:

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't mmap\n");return -1;
}

这里 screen_size 计算的是整个屏幕的字节数,mmap 将其映射到 fb_base,通过 fb_base 就可以访问 Framebuffer 进行像素操作。

5. 绘制像素点

lcd_put_pixel 函数用于在指定位置绘制像素点,支持 8 位、16 位(RGB565)和 32 位(ARGB8888)三种颜色格式。

void lcd_put_pixel(int x, int y, unsigned 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;break;case 16:red = (color >> 16) & 0xff;green = (color >> 8) & 0xff;blue = (color >> 0) & 0xff;color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);*pen_16 = color;break;case 32:*pen_32 = color;break;default:printf("can't support %dbpp\n", var.bits_per_pixel);break;}
}

不同位深度的处理

  • 8 位模式:直接存储颜色索引值。
  • 16 位模式:转换 24 位 RGB 颜色到 RGB565 格式。
  • 32 位模式:直接存储完整的 ARGB8888 颜色值。

6. 清屏操作

在 Framebuffer 应用中,清屏通常指将整个屏幕填充为某种颜色。例如,将屏幕全部填充为白色:

memset(fb_base, 0xff, screen_size);

7. 示例:绘制红色像素点

下面的代码在屏幕中央绘制 100 个红色像素点(颜色值 0xFF0000 表示红色):

for (int i = 0; i < 100; i++) {lcd_put_pixel(var.xres / 2 + i, var.yres / 2, 0xFF0000);
}

8. 资源释放

使用完 Framebuffer 之后,需要释放映射的内存并关闭设备文件:

munmap(fb_base, screen_size);
close(fd_fb);

9. 总结

本篇文章介绍了 Linux Framebuffer 的基本概念,并通过示例代码讲解了 Framebuffer 设备的初始化、内存映射、像素绘制和清屏等操作。

关键步骤回顾

  1. 打开 Framebuffer 设备 (open /dev/fb0)
  2. 获取屏幕信息 (ioctl 获取 fb_var_screeninfo)
  3. 内存映射 (mmap 将显存映射到用户空间)
  4. 绘制像素点(根据不同位深度处理颜色格式)
  5. 清屏 (memset 填充屏幕颜色)
  6. 释放资源 (munmapclose)

Framebuffer 编程适用于嵌入式 Linux、图形驱动开发和 GUI 渲染,掌握这些基本操作有助于深入理解图形系统的底层机制。


http://www.ppmy.cn/devtools/168653.html

相关文章

Redis原理--持久化

Redis的数据都保存在内存&#xff0c;如果Redis宕机&#xff0c;数据将会全部丢失&#xff0c;因此必须有一种机制来保证Redis里的数据不会因为故障而丢失&#xff0c;这种机制就是Redis的持久化机制。 Redis持久化机制 1、快照 快照是一次全量备份&#xff0c;快照是内存数…

最近比突出的DeepSeek与ChatGPT的详细比较分析

引言 随着人工智能技术的快速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域涌现出了许多强大的模型和工具。DeepSeek和ChatGPT作为其中的代表&#xff0c;各自在特定领域和应用场景中展现了卓越的性能。本文将从多个维度对DeepSeek和ChatGPT进行比较分析&…

Java学习打卡-Day19-Set、HashSet、LinkedHashSet

Set 接口 无序&#xff08;添加和取出顺序不一致&#xff09;&#xff08;但取出顺序固定&#xff09;。没有索引。不允许重复&#xff0c;所以最多一个null。遍历方式 迭代器增强for循环不能使用普通for循环索引方式。 HashSet 实现了Set接口&#xff0c;具有相应特征。底…

Java 集合框架

一、引言 在 Java 编程中,集合是一种非常重要的数据结构,它可以用来存储和管理一组对象。Java 集合框架提供了一套丰富的接口和类,用于处理不同类型的集合,如列表、集合、映射等。通过使用集合框架,开发者可以更高效地处理数据,提高代码的可维护性和可扩展性。 二、Jav…

WEB攻防-PHP反序列化-字符串逃逸

目录 前置知识 字符串逃逸-减少 字符串逃逸-增多 前置知识 1.PHP 在反序列化时&#xff0c;语法是以 ; 作为字段的分隔&#xff0c;以 } 作为结尾&#xff0c;在结束符}之后的任何内容不会影响反序列化的后的结果 class people{ public $namelili; public $age20; } var_du…

跨系统投屏:Realme手机(远程)投屏到Linux系统的简单方法

家里长辈年纪上来了&#xff0c;有点老花眼&#xff0c;平常看手机总是觉得字体不够大&#xff0c;还一个劲儿地将手机拿很远。其实那台手机的字体已经调到最大了。 为了让长辈刷手机的时候可以轻松快乐一点&#xff0c;我们帮他将手机投屏到电脑上。毕竟电脑屏幕比手机大多了&…

正则表达式(可用于MySQL、C++、Python)

正则表达式&#xff08;Regular Expression&#xff0c;简称 regex 或 regexp&#xff09;是一种用于描述文本模式的字符串。它通过特定的语法规则&#xff0c;允许你匹配、搜索和操作字符串中的内容。 正则表达式可以用来&#xff1a; 匹配文本&#xff1a;可以在字符串中查…

【Linux】浅谈环境变量和进程地址空间

一、环境变量 基本概念 环境变量&#xff08;Environment Variables&#xff09;是操作系统提供的一种机制&#xff0c;用于存储和传递配置信息、系统参数、用户偏好设置等。 环境变量的作用 配置程序行为&#xff1a; 程序可以通过环境变量获取配置信息&#xff0c;例如日…