笔记整理—linux驱动开发部分(8)framebuffer类设备

framebuffer显示设备。

在应用层直接抽象位向DDR中存放图片。

在操作系统中,将上图分为两个部分:驱动+应用。

使用复制的方法效率十分的低,所以有了内存映射方法实现图片的显示。

framebuffer帧(铺满一个屏幕)(fd)在linux在虚拟出一个设备/dev/fd,是向应用层提供的接口,也是同一接口,是一种直接抽象。

frambuffer使用方法:①打开设备/dev/fdn;②获取设备信息<linux/fd.h>;③mmp映射(原因是应用层工作在应用层空间,内核工作在内核空间,两块虚拟空间不同,但映射到了同一块物理空间)。多个进程可同时操作同一LCD,无非是谁覆盖谁;④填充framebuffer。

fb在应用层的使用:

复制代码
#define FBDEVICE "/dev/fb0"

fd = open(FBDEVICE, O_RDWR);//①打开设备
if(fd<0)
{
    //err
}

#define FBIOPUT_VSCREENINFO与#define FBIOGET_FSCREENINFO宏是位于linux/fb.h下的宏,其中FBIOPUT_VSCREENINFO是可变的fb信息而FBIOGET_FSCREENINFO是不可变信息。不可变信息:如硬件真实分辨率(分辨率最大值,1080p显示器可支持720p的显示);可变信息:可适分辨率、虚拟分辨率、参考点等。

复制代码
struct fb_fix_screeninfo finfo = {0};//在<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 reserved[3];		/* Reserved for future compatibility */
};//具体情况

ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);//获取设备信息(不可变)
if(ret<0)
{
    //err
}

fb大小是屏幕的一倍,用于做双缓冲(乒乓结构)。

smem_len(字节)=虚拟分辨率(x*y)*bpp(32/8) <=色彩位(aRGB)。

复制代码
unsigned int *pfb = NULL;
unsigned long smem_len= vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;

pfb = mmap(NULL, smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
//NULL 自分配地址(应用层)
//smem_len长度
//PROT_READ | PROT_WRITE可读可写
//MAP_SHARED非排它
//0 偏移量

if (NULL == pfb)
{
	//err
}

void draw_back(unsigned int width, unsigned int height, unsigned int color)//纯色填充
{
	unsigned int x, y;
	
	for (y=0; y<height; y++)
	{
		for (x=0; x<width; x++)
		{
			*(pfb + y * WIDTH + x) = color;
		}
	}
}

draw_back(WIDTH, HEIGHT, 0xffffffff);//白

在对vinfo进行修改后,使用ioctl写回:

复制代码
ret=ioctl(fd,FBIOGET_VSCREENINFO,&vinfo);

可视分辨率只能在驱动中修改。

先介绍到这吧,下一章介绍framebuffer框架与fb驱动相关。

相关推荐
xiaoye-duck20 分钟前
《Linux系统编程》Linux 进程间通信之管道基础解析:从匿名管道原理到基于管道的进程池实现
linux
z2005093024 分钟前
【Linux学习】Linux中的进程程序替换
linux·服务器·学习
小+不通文墨28 分钟前
把树莓派外接的DHT11接收的温湿度发送到emqx上
经验分享·笔记·嵌入式硬件·学习·树莓派
bush442 分钟前
嵌入式linux学习记录四
linux·运维·学习
Deitymoon1 小时前
FreeRTOS——列表与列表项
stm32·单片机·嵌入式硬件
总结所学1 小时前
电路定理 叠加定理 基尔霍夫定律
单片机·嵌入式硬件
会编程的土豆1 小时前
Go 方法接收者超清晰笔记(类型名 vs 变量名)
开发语言·笔记·golang
lihao lihao2 小时前
软硬链接
linux·运维·服务器
fanged2 小时前
C++的汇编实现(TODO)
笔记