Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

时间:2022-01-03 23:08:46

一、Framebuffer 设备驱动总体架构

帧缓冲设备为标准的字符型设备,在Linux中主设备号29,定义在/include/linux/major.h中的FB_MAJOR,次设备号定义帧缓冲的个数,最大允许有32个FrameBuffer,定义在/include/linux/fb.h中的FB_MAX,对应于文件系统下/dev/fb%d设备文件。

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

我们从上面这幅图看,帧缓冲设备在Linux中也可以看做是一个完整的子系统,大体由fbmem.c和xxxfb.c组成。向上给应用程序提供完善的设备文件操作接口(即对FrameBuffer设备进行read、write、ioctl等操作),接口在Linux提供的fbmem.c文件中实现;向下提供了硬件操作的接口,只是这些接口Linux并没有提供实现,因为这要根据具体的LCD控制器硬件进行设置,所以这就是我们要做的事情了(即xxxfb.c部分的实现)。

二 、Framebuffer 相关的重要数据结构:

1、从Framebuffer设备驱动程序结构看,该驱动主要跟fb_info结构体有关,该结构体记录了Framebuffer设备的全部信息,包括设备的设置参数、状态以及对底层硬件操作的函数指针。在Linux中,每一个Framebuffer设备都必须对应一个fb_info,fb_info在/linux/fb.h中的定义如下:(只列出重要的一些)

 struct fb_info {
atomic_t count;
int node; ///次设备号
int flags;
struct mutex lock; //用于open、release、ioctrl功能的锁
struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */
struct fb_var_screeninfo var; //LCD 可变参数
struct fb_fix_screeninfo fix; //LCD 固定参数
struct fb_monspecs monspecs; /* Current Monitor specs *///LCD 显示器标准
struct work_struct queue; //帧缓冲事件队列
struct fb_pixmap pixmap; ///图像硬件 mapper
struct fb_pixmap sprite; //光标硬件 mapper
struct fb_cmap cmap; //当前颜色表
struct list_head modelist; //模式列表
struct fb_videomode *mode; //当前的显示模式 #ifdef CONFIG_FB_BACKLIGHT
/* assigned backlight device */
/* set before framebuffer registration,
remove after unregister */
struct backlight_device *bl_dev;///对应的背光设备 /* Backlight level curve */
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];///背光调整
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif struct fb_ops *fbops;///---->对底层硬件设备操作的函数指针
struct device *device; /* This is the parent *////父设备节点
struct device *dev; /* This is this fb device *////当前的帧缓冲设备
int class_flag; /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting *///图块Blitting ?
#endif
char __iomem *screen_base; /* Virtual address *///虚拟地址
unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ ///LCD IO映射的虚拟内存大小
void *pseudo_palette; /* Fake palette of 16 colors *///伪16色 颜色表
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend *////LCD 挂起或复位的状态
void *fbcon_par; /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
/* we need the PCI or similar aperture base/size not
smem_start/size as smem_start may just be an object
allocated inside the aperture so may not actually overlap */
struct apertures_struct {
unsigned int count;
struct aperture {
resource_size_t base;
resource_size_t size;
} ranges[];
} *apertures; bool skip_vt_switch; /* no VT switch on suspend/resume required */
};

其中,fb_var_screeninfo和fb_fix_screeninfo两个结构体跟LCD硬件属性相关,fb_var_screeninfo代表可修改的LCD显示参数,如分辨率和像素比特数;fb_fix_screeninfo代表不可修改的LCD属性参数,如显示内存的物理地址和长度等。另外一个非常重要的成员是fb_ops,其是LCD底层硬件操作接口集。

fb_ops硬件操作接口集包含很多接口,如设置可变参数fb_set_par、设置颜色寄存器fb_setcolreg、清屏接口fb_blank、画位图接口fb_imageblit、内存映射fb_mmap等等。

fb_info结构体在调用register_framebuffer之前完成初始化。一般来说,LCD设备属于平台设备,其初始化是在平台设备驱动的probe接口完成。而LCD设备所涉及的硬件初始化则在平台设备初始化中完成。

2、fb_fix_screeninfo结构体主要记录用户不可以修改的控制器的参数,该结构体的定义如下:

 struct fb_fix_screeninfo {
char id[]; //字符串形式的标识符
unsigned long smem_start; /fb 缓存的开始位置
/* (physical address) */
__u32 smem_len; /* Length of frame buffer mem *///fb 缓存的长度
__u32 type; /* see FB_TYPE_* *////看FB_TYPE_* -->
__u32 type_aux; /* Interleave for interleaved Planes *///分界
__u32 visual; ///看FB_VISUAL_* -->
__u16 xpanstep; //如果没有硬件panning就赋值为0
__u16 ypanstep; //如果没有硬件panning就赋值为0
__u16 ywrapstep; //如果没有硬件ywrap就赋值为0
__u32 line_length; //一行的字节数
unsigned long mmio_start; //内存映射 IO的开始位置
/* (physical address) */
__u32 mmio_len; //内存映射 IO的长度
__u32 accel; /* Indicate to driver which */
/* specific chip/card we have */
__u16 capabilities; /* see FB_CAP_* *///功能 ---FB_CAP_FOURCC--- Device supports FOURCC-based formats
__u16 reserved[]; //为以后的兼容性保留
};

3、fb_var_screeninfo结构体主要记录用户可以修改的控制器的参数,比如屏幕的分辨率和每个像素的比特数等,该结构体定义如下:

 struct fb_var_screeninfo { ///显示屏信息
__u32 xres; /* visible resolution*//可视区域,一行有多少个像素点
__u32 yres; ///可视区域,一列有多少个像素点
__u32 xres_virtual; /* virtual resolution*//虚拟区域,一行有多少个像素点,简单的意思就是内存中定义的区间是比较大的
__u32 yres_virtual;////虚拟区域,一列有多少个像素点
__u32 xoffset; //虚拟到可见屏幕之间的行偏移
__u32 yoffset; /* resolution *//虚拟到可见屏幕之间的列偏移 __u32 bits_per_pixel; /* guess what*/ 每个像素的 bit 数,这个参数不需要自己配置,而是通过上层在调用 checkvar 函数传递 bpp 的时候赋值的
__u32 grayscale; /* 0 = color, 1 = grayscale,*////等于零就成黑白 (灰度)
/* >1 = FOURCC */
// 通过 pixel per bpp 来设定 red green 和 blue 的位置; pixel per bpp 可以通过 ioctl 设定
struct fb_bitfield red; //fb缓存的R位域
struct fb_bitfield green; /* else only length is significant *//fb缓存的G位域
struct fb_bitfield blue; //fb缓存的B位域
struct fb_bitfield transp; /* transparency *//透明度 __u32 nonstd; /* != 0 Non standard pixel format *///如果nonstd 不等于0,非标准的像素格式 __u32 activate; /* see FB_ACTIVATE_* */ __u32 height; //内存中的图像高度
__u32 width; //内存中的图像宽度 __u32 accel_flags; /* (OBSOLETE) see fb_info.flags *////加速标志 /* Timing: All values in pixclocks, except pixclock (of course) */
///时序,这些部分就是显示器的显示方法了,和具体的液晶显示屏有关,在驱动中一般放在 具体液晶屏的配置文件
__u32 pixclock; /* pixel clock in ps (pico seconds) *///像素时钟
__u32 left_margin; /* time from sync to picture *////行切换,从同步到绘图之间的延迟
__u32 right_margin; /* time from picture to sync *///行切换,从绘图到同步之间的延迟
__u32 upper_margin; /* time from sync to picture *///帧切换,从同步到绘图之间的延迟
__u32 lower_margin; ////帧切换,从绘图到同步之间的延迟
__u32 hsync_len; /* length of horizontal sync */ //水平同步的长度
__u32 vsync_len; /* length of vertical sync */ //垂直同步的长度
__u32 sync; /* see FB_SYNC_* *////---->看 FB_SYNC_*
__u32 vmode; /* see FB_VMODE_* *////---->看 FB_VMODE_*
__u32 rotate; /* angle we rotate counter clockwise */
__u32 colorspace; /* colorspace for FOURCC-based modes */
__u32 reserved[]; /* Reserved for future compatibility */
};

通过下图可以对fb_var_screeninfo中涉及的时序理解更清楚一些:

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

4、fb_ops结构体是对底层硬件操作的函数指针,该结构体中定义了对硬件的操作有:

注: fb_ops结构与file_operations 结构不同,fb_ops是底层操作的抽象,file_operations是提供给上层系统调用的接口,可以直接调用.

 struct fb_ops {
/* open/release and usage marking */
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/*对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要*/ 
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);///检查可变参数并进行设置
/* set the video mode according to info->var */
int (*fb_set_par)(struct fb_info *info);///根据设置的值进行更新,使之有效
/* set color register */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, ////设置颜色寄存器
unsigned blue, unsigned transp, struct fb_info *info);
/* set color registers in batch */
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

int (*fb_blank)(int blank, struct fb_info *info);///显示空白
/*pan显示*/
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);///矩形填充
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);///复制数据
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);///图形填充
/* 绘制光标 */
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
/* 旋转显示 */
void (*fb_rotate)(struct fb_info *info, int angle);
/* 等待blit空闲 */
int (*fb_sync)(struct fb_info *info);
/* fb 特定的 ioctl */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);
/* 处理32bit compat ioctl (optional) */
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);
/* fb 特定的 mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
/* get capability given var */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
struct fb_var_screeninfo *var);
/* teardown any resources to do with this framebuffer */
void (*fb_destroy)(struct fb_info *info);
/* called at KDB enter and leave time to prepare the console */
int (*fb_debug_enter)(struct fb_info *info);
int (*fb_debug_leave)(struct fb_info *info);
};

5、fb_cmap:设备独立的 colormap 信息,可以通过 ioctl 的 FBIOGETCMAP 和 FBIOPUTCMAP 命令设置 colormap;

struct fb_cmap { //颜色映射表
__u32 start; /* First entry *////第一个入口
__u32 len; /* Number of entries *///入口的数字
__u16 *red; /* Red values *///红色
__u16 *green; ///绿色
__u16 *blue; ///蓝色
__u16 *transp; //透明度,允许为空
};

这些结构相互之间的关系如下所示:

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体

Framebuffer 驱动学习总结(一) ---- 总体架构及关键结构体的更多相关文章

  1. ARM-Linux S5PV210 UART驱动(3)----串口核心层、关键结构体、接口关系

    尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中的成员函数,但是Linux已经在文件serial_core.c中实 ...

  2. Framebuffer 驱动学习总结(二)---- Framebuffer模块初始化

    ---恢复内容开始--- Framebuffer模块初始化过程:--driver\video\fbmem.c 1.  初始化Framebuffer: FrameBuffer驱动是以模块的形式注册到系统 ...

  3. 大数据学习--day16(集合总体架构--ArrayList--LinkedList)

    集合总体架构--ArrayList--LinkedList Collection接口的实现类用法上都有相似的方法.Map同理. List: 特性 :      1. 有索引     2. 有序     ...

  4. go培训课程都学什么?xorm框架学习系列(二):xorm结构体映射规则和表操作

    上节内容我们学习了基本的xorm框架的知识和基础配置的相关信息.本节课内容我们继续学习相关的知识和相关操作. 名称映射规则 名称映射规则主要负责结构体名称到表名和结构体field到表字段的名称映射. ...

  5. Linux设备驱动--块设备(二)之相关结构体

    上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...

  6. Linux设备驱动--块设备(二)之相关结构体(转)

    上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...

  7. 【学习笔记】【C语言】结构体

    1.定义结构体变量的3种方式 1> 先定义类型,再定义变量(分开定义) struct Student {    int age; }; struct Student stu;  2> 定义 ...

  8. 菜鸟学习-C语言函数参数传递详解-结构体与数组 分类: C/C++ Nginx 2015-07-14 10:24 89人阅读 评论(0) 收藏

    C语言中结构体作为函数参数,有两种方式:传值和传址. 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数.在这种情况下 ...

  9. GO语言学习(十六)Go 语言结构体

    Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型. 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 结构体表示一项记录,比如保存图 ...

随机推荐

  1. bzoj3110树套树

    wa一片,最后一个T,终于心碎了... 为什么没人告诉我要开longlong 为什么所有人都说没有负数 #include<cstdio> #include<algorithm> ...

  2. linux dump 命令详解

    功能说明:备份文件系统. 语 法:dump [-cnu][-0123456789][-b <区块大小>][-B <区块数目>][-d <密度>][-f <设备 ...

  3. iOS 9之New UIKit for International User Interfaces

    金田 Apple一直是注重用户体验的典范,而此次在UI上面,更是做到极致.此次iOS 9的发布能完全支持阿拉伯语.希伯来语等书写和阅读方式为从右向左的语言环境.不仅仅是简单的基础文本,而是支持将界面翻 ...

  4. Qt的信号槽,一个老MFC的经验

    最近在利用闲暇时间研究Qt,大概有3周了,看过了官网的white paper并浏览了一遍<C++ GUI Programming with Qt 4, 2nd Edition>.总的来说, ...

  5. 启动Jupyter Notebook

    按照图所示,在命令下输入ipython notebook 即可启动Jupyter. 启动后的效果:

  6. requests保持登录session &comma;cookie 和 token

    一.request提供了一个一个叫做session的类,来实现客户端和服务端的会话保持 # coding:utf-8 import requests url = "https://passp ...

  7. MyEclipse10安装Log4E插件

    一. Log4E插件下载 下载地址:http://log4e.jayefem.de/content/view/3/2/ 二.安装Log4E插件 将下载下来的压缩包解压缩,如下图所示: 解压缩生成的[d ...

  8. 【UVa】11882 Biggest Number(dfs&plus;剪枝)

    题目 题目     分析 典型搜索,考虑剪枝. 统计一下联通分量. 1.本位置能够达到所有的点的数量加上本已有的点,还没有之前的结果长,直接返回. 2.当本位置能够达到所有的点的数量加上本已有的点与之 ...

  9. 【逆序对相关&sol;数学】【P1966】【NOIP2013D1T2】 火柴排队

    传送门 Description 涵涵有两盒火柴,每盒装有 $n$ 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为:$ \sum ...

  10. 用python的turtle画分形树

    由于分形树具有对称性,自相似性,所以我们可以用递归来完成绘制.只要确定开始树枝长.每层树枝的减短长度和树枝分叉的角度,我们就可以把分形树画出来啦!! 代码如下: # -*- coding: utf-8 ...