Framebuffer编程

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

static int fd_fb;
static struct fb_var_screeninfo var;	/* Current var */
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;

/**********************************************************************
 * 函数名称: lcd_put_pixel
 * 功能描述: 在LCD指定位置上输出指定颜色(描点)
 * 输入参数: x坐标,y坐标,颜色
 * 输出参数: 无
 * 返 回 值: 会
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2020/05/12	     V1.0	  zh(angenao)	      创建
 ***********************************************************************/ 
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:
		{
			/* 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;
			break;
		}
		case 32:
		{
			*pen_32 = color;
			break;
		}
		default:
		{
			printf("can't surport %dbpp\n", var.bits_per_pixel);
			break;
		}
	}
}

int main(int argc, char **argv)
{
	int i;
	
	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;
	}

	line_width  = var.xres * var.bits_per_pixel / 8;
	pixel_width = var.bits_per_pixel / 8;
	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;
	}

	/* 清屏: 全部设为白色 */
	memset(fb_base, 0xff, screen_size);

	/* 随便设置出100个为红色 */
	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;	
}

在嵌入式系统开发中,经常需要对LCD显示屏进行像素级的控制。Linux Framebuffer是一个强大的接口,它允许开发者直接操作显示内存。本文将通过一个简单的C语言程序示例,解析如何在基于Linux Framebuffer的嵌入式系统中控制LCD像素。

一、程序功能概述

本示例程序的功能是在LCD屏上绘制100个红色像素点。程序首先打开Framebuffer设备,获取当前屏幕信息,然后通过内存映射访问Framebuffer,最后在指定位置绘制像素点,并在绘制完成后清理资源。

二、Framebuffer基础

Framebuffer是一个内存区域,其中包含了当前显示的图像数据。通过读写这个内存区域,可以控制显示在屏幕上的图像。

关键结构体和接口

  • fb_var_screeninfo:描述屏幕的当前变量配置,如分辨率、颜色深度等。
  • ioctl():用于执行设备控制请求,如获取屏幕信息。
  • mmap():内存映射,允许程序直接操作Framebuffer内存。

三、程序代码解析

1. 包含头文件

#include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> ...

这些头文件提供了Framebuffer操作所需的函数和类型定义。

2. 定义全局变量

static int fd_fb; static struct fb_var_screeninfo var; static int screen_size; static unsigned char *fb_base; static unsigned int line_width; static unsigned int pixel_width;

这些变量用于存储Framebuffer文件描述符、屏幕信息、屏幕大小、Framebuffer内存地址等。

3. lcd_put_pixel函数

void lcd_put_pixel(int x, int y, unsigned int color) { ... }

该函数根据屏幕的颜色深度,将指定颜色的像素点绘制到指定位置。

4. main函数

int main(int argc, char **argv) { ... }

main函数是程序的入口点,它执行以下步骤:

  • 打开Framebuffer设备。
  • 获取屏幕变量信息。
  • 计算每行的字节数和每个像素的字节数。
  • 内存映射Framebuffer。
  • 清屏并绘制100个红色像素点。
  • 清理资源,包括munmap和close。

四、Framebuffer设备操作

程序通过open函数打开/dev/fb0设备文件,然后使用ioctl函数获取屏幕信息,最后通过mmap将Framebuffer内存映射到用户空间,以便直接访问。

五、绘制像素点

根据屏幕的颜色深度,程序计算每个像素在Framebuffer中的位置,并将其设置为指定颜色。这里考虑了8位、16位和32位颜色深度的情况。

六、资源清理

绘制完成后,程序使用munmap函数取消Framebuffer的内存映射,并使用close函数关闭Framebuffer设备。

七、总结

本文通过一个简单的示例程序,展示了如何在Linux Framebuffer上进行像素级的控制。这在嵌入式系统开发中非常有用,尤其是在需要直接操作显示内存的场景。

通过本示例,读者可以了解到Framebuffer的基本使用方法,以及如何在实际开发中应用这些技术。Framebuffer提供了一种灵活且强大的方式,用于控制嵌入式系统中的显示输出

  

相关推荐

  1. 嵌入式Linux—Framebuffer应用编程

    2024-07-12 00:34:04       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 00:34:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 00:34:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 00:34:04       57 阅读
  4. Python语言-面向对象

    2024-07-12 00:34:04       68 阅读

热门阅读

  1. mvvm模式

    2024-07-12 00:34:04       25 阅读
  2. Mybatis-Plus最优化持久层开发

    2024-07-12 00:34:04       20 阅读
  3. C++ 定时器触发

    2024-07-12 00:34:04       23 阅读
  4. SqlSugar分表笔记

    2024-07-12 00:34:04       25 阅读
  5. 模板语法指令语法——02

    2024-07-12 00:34:04       21 阅读
  6. LeetCode 算法:实现 Trie (前缀树) c++

    2024-07-12 00:34:04       21 阅读