linux驱动系列学习之Framebuffer子系统(三)

一、Framebuffer子系统简介
        Framebuffer(帧缓冲)时Linux系统位显示设备提供的一个接口。属于偏底层的显示接口。它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。对于帧缓冲设备而言,只要在缓冲区对应位置写入颜色值,对应的屏幕位置则显示响应的颜色。
         Framebuffer子系统的主要结构如下图(借图展示,侵删)。


        从中可以看到,Framebuffer子系统主要通过fb_ops中的成员函数操作LCD显示器。多数的LCD操作规范,可以按照像素点格式的要求按顺序写入帧缓冲区。但是也有一些LCD操作不是很规范,这时,可以使用fb_ops中的fb_write()函数重写。例如spi接口或i2c的0.96寸、分辨率位128×64的oled屏幕,可以使用fb_write()重写。

二、i2c接口的oled屏幕驱动

1. 重要结构体

使用Framebuffer子系统,主要需要配置如下几个重要的结构体:

fb_var_screeninfo代表可修改的LCD显示参数,如分辨率和像素比特数。

fb_fix_screeninfo 代表不可修改的LCD属性参数,如显示内存的物理地址和长度等。

fb_ops,其是LCD底层硬件操作接口集。

fb_cmap,颜色映射表。

fb_info,   Framebuffer子系统主要注册结构体。

fb_info具体如下:

#define OLED_WIDTH     128
#define OLED_HEIGHT    64

static struct fb_info oled_info = {
	.var ={
		.xres = OLED_WIDTH, 		
		.yres = OLED_HEIGHT,
		.xres_virtual = OLED_WIDTH, 		
		.yres_virtual = OLED_HEIGHT,
		.bits_per_pixel = 1,
	},
	.fix={
		.smem_len = OLED_HEIGHT * OLED_WIDTH / 8,			
		.line_length = 128,
	},
	.fbops = &oled_fbops,
};

从上述配置fb_info结构体可以看到,主要配置屏幕的长(xres)、宽(yres)、一个像素显示需要多少位(bits_per_pixel)、显示一帧需要多少字节(smem_len)、一行多少字节(line_length)和一个fb_ops结构体。

其中oled_fbops结构体如下:

static struct fb_ops oled_fbops = {
	.fb_open      = oled_fb_open,
	.fb_release   = oled_fb_release,
    .fb_write     = oled_fb_write,
	.fb_mmap      = oled_fb_mmap,
}

fb_open、release是打开关闭设备,fb_mmap则是对设备进行抽象的函数,开辟显存的地方,使显存和屏幕显示对应。fb_write则是oled显示是i2c接口的显示屏,故需要对其进行重写。

2. 注册、卸载Framebuffer子系统

注册和卸载需要两个函数:

int register_framebuffer(struct fb_info *fb_info);  //用于注册显示设备

int unregister_framebuffer(struct fb_info *fb_info);  //卸载

三、总结

        Framebuffer子系统是Linux系统对显示相关的硬件的一个软件抽象层,其最终是挂载到platform总线上,在probe函数中会调用相关操作。Linux显示目前有两种方式,一种是Framebuffer子系统,另一种则是DRM/KMS,前者比较简单,通过的功能也不多,后者现在是更主流的方式,也复杂很多,等学习了之后再更新。

参考书:Linux设备驱动开发详解(基于最新的Linux4.0内核) 宋宝华著

猜你喜欢

转载自blog.csdn.net/zichuanning520/article/details/124061493