帧缓冲子系统框架

1  Linux帧缓冲子系统

帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,它把显示设备描述成一个缓冲区,允许应用程序在图形模式下直接对显示显示缓冲区进行读写操作。

帧缓冲是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。通过不断的向帧缓冲写入数据,显示控制器就自动的从帧缓冲中读取数据并显示出来。帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示设备,Linux下还可支持多个帧缓冲设备,最多可达32个,分别为/dev/fb0~fb31,帧缓冲设备为字符设备,主设备号为29,次设备号则从0~31。

Linux帧缓冲子系统的层次结构图:

帧缓冲子系统由帧缓冲设备层和控制器驱动组成。帧缓冲设备层在drivers/video/fbmem.c中实现,向上给应用程序提供完善的设备文件操作接口,向下提供硬件操作接口。控制器驱动命名为xxxfb.c文件。

2  显示缓冲区和显示点

在帧缓冲设备中,对屏幕显示点的操作通过读写显示缓冲区来完成,在不同的色彩模式下,显示缓冲区和屏幕上的显示点有不同的对应关系。

这里主要介绍16位色:



15~11


10~5


4~0


RGB565


R


G


B

3  帧缓冲数据结构

(1)fb_info

fb_info是帧缓冲子系统中最重要的结构(FBI)。它记录了帧缓冲设备的全部信息,包括设备的设置参数、状态以及操作函数指针。每一个帧缓冲设备都必须对应一个fb_info。

 1 /* include/linux/fb.h */
 2 struct fb_info {
 3     atomic_t count;
 4     int node;
 5     int flags;
 6     struct mutex lock;    // 用于open/release/ioctl的锁
 7     struct mutex mm_lock;
 8     struct fb_var_screeninfo var;    // 可变参数
 9     struct fb_fix_screeninfo fix;    // 固定参数
10     struct fb_monspecs monspecs;    // 显示器标准
11     struct work_struct queue;    // 帧缓冲事件队列
12     struct fb_pixmap pixmap;    // 图像硬件mapper
13     struct fb_pixmap sprite;    // 光标硬件mapper
14     struct fb_cmap cmap;    // 目前的颜色表
15     struct list_head modelist;
16     struct fb_videomode *mode;    // 目前的video模式
17
18 #ifdef CONFIG_FB_BACKLIGHT
19     /* 对应的背光设备 */
20     struct backlight_device *bl_dev;
21
22     /* 背光调整 */
23     struct mutex bl_curve_mutex;
24     u8 bl_curve[FB_BACKLIGHT_LEVELS];
25 #endif
26 #ifdef CONFIG_FB_DEFERRED_IO
27     struct delayed_work deferred_work;
28     struct fb_deferred_io *fbdefio;
29 #endif
30
31     struct fb_ops *fbops;    // fb_ops帧缓冲操作
32     struct device *device;      // 父设备
33     struct device *dev;    // fb设备
34     int class_flag;    // 私有sysfs标志
35 #ifdef CONFIG_FB_TILEBLITTING
36     struct fb_tile_ops *tileops;    // 图块Blitting
37 #endif
38     char __iomem *screen_base;    // 虚拟基地址
39     unsigned long screen_size;    // ioremapped的虚拟内存大小
40     void *pseudo_palette;    // 伪16色颜色表
41 #define FBINFO_STATE_RUNNING    0
42 #define FBINFO_STATE_SUSPENDED  1
43     u32 state;    // 硬件状态,如挂起
44     void *fbcon_par;
45     void *par;
46     struct apertures_struct {
47         unsigned int count;
48         struct aperture {
49             resource_size_t base;
50             resource_size_t size;
51         } ranges[0];
52     } *apertures;
53
54     bool skip_vt_switch;
55 };

(2)fb_ops

在fb_info结构体中包含了一个重要的操作集合,即fb_ops,描述了特定帧缓冲设备的具体操作方法。

 1 /* include/linux/fb.h */
 2 struct fb_ops {
 3     /* 打开/释放 */
 4     struct module *owner;
 5     int (*fb_open)(struct fb_info *info, int user);
 6     int (*fb_release)(struct fb_info *info, int user);
 7
 8     /* 对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要 */
 9     ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
10                size_t count, loff_t *ppos);
11     ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
12                 size_t count, loff_t *ppos);
13
14     /* 检测可变参数,并调整到支持的值 */
15     int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
16
17     /* 根据info->var设置video模式 */
18     int (*fb_set_par)(struct fb_info *info);
19
20     /* 设置color寄存器 */
21     int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
22                 unsigned blue, unsigned transp, struct fb_info *info);
23
24     /* 批量设置color寄存器,设置颜色值 */
25     int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
26
27     /* 显示空白 */
28     int (*fb_blank)(int blank, struct fb_info *info);
29
30     /* pan显示 */
31     int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
32
33     /* 矩形填充 */
34     void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
35     /* 数据复制 */
36     void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
37     /* 图形填充 */
38     void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
39
40     /* 绘制光标 */
41     int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
42
43     /* 旋转显示 */
44     void (*fb_rotate)(struct fb_info *info, int angle);
45
46     /* 等待blit空闲(可选) */
47     int (*fb_sync)(struct fb_info *info);
48
49     /* fb特定的ioctl(可选) */
50     int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
51             unsigned long arg);
52
53     /* 处理32位的compat ioctl(可选) */
54     int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
55             unsigned long arg);
56
57     /* fb特定的mmap */
58     int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
59
60     void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
61                 struct fb_var_screeninfo *var);
62
63     /* teardown any resources to do with this framebuffer */
64     void (*fb_destroy)(struct fb_info *info);
65
66     /* called at KDB enter and leave time to prepare the console */
67     int (*fb_debug_enter)(struct fb_info *info);
68     int (*fb_debug_leave)(struct fb_info *info);

  • fb_check_var()成员函数用于检查可变的屏幕参数并调整到合适的值;
  • fb_set_par()则使得用户设置的屏幕参数在硬件上有效。

(3)fb_var_screeninfo/fb_fix_screeninfo

这两个结构用来描述帧缓冲设备的可变参数和固定参数,也是fb_info的成员var和fix的结构体类型。fb_var_screeninfo记录了帧缓冲设备和特定显示模式中设备无关的可变信息,可变是指能被用户空间修改,例如我们可以通过ioctl()命令FBIOGET_VSCREENINFO/FBIOPUT_VSCREENINFO获取和设置这些参数。

fb_fix_screeninfo记录了帧缓冲设备和特定显示模式中设备无关的不可变的信息,也就是说这些信息我们无法在用户空间修改,但可以通过ioctl命令FBIOGET_FSCREENINFO获取固定参数。

 1 /* include/linux/fb.h */
 2 struct fb_var_screeninfo {
 3     /* 可见分辨率 */
 4     __u32 xres;
 5     __u32 yres;
 6     /* 虚拟分辨率 */
 7     __u32 xres_virtual;
 8     __u32 yres_virtual;
 9     /* 虚拟到可见之间的偏移 */
10     __u32 xoffset;
11     __u32 yoffset;
12
13     __u32 bits_per_pixel;    // 每像素位数,BPP
14     __u32 grayscale;    // 非0时指灰度
15
16     /* fb缓存的R\G\B位域 */
17     struct fb_bitfield red;
18     struct fb_bitfield green;
19     struct fb_bitfield blue;
20     struct fb_bitfield transp;    // 透明度
21
22     __u32 nonstd;    // !=0非标准像素格式
23
24     __u32 activate;
25
26     __u32 height;    // 高度
27     __u32 width;    // 宽度
28
29     __u32 accel_flags;    // 看fb_info.flags
30
31     /* 定时,除了pixclock本身外,其他的都以像素时钟为单位 */
32     __u32 pixclock;    // 像素时钟(皮秒)
33     __u32 left_margin;    // 行切换,从同步到绘图之间的延迟
34     __u32 right_margin;    // 行切换,从绘图到同步之间的延迟
35     __u32 upper_margin;    // 帧切换,从绘图到同步之间的延迟
36     __u32 lower_margin;
37     __u32 hsync_len;    // 水平同步的长度
38     __u32 vsync_len;    // 垂直同步的长度
39     __u32 sync;
40     __u32 vmode;
41     __u32 rotate;    // 顺时钟旋转的角度
42     __u32 colorspace;
43     __u32 reserved[4];    // 保留
44 };

重点关注xres、yres、xres_virtual、yres_virtual、xoffset和yoffset这几个成员。

由于LCD控制器或者图像显示卡所支持的最大帧缓冲内存可能大于屏幕可显示的像素内存,于是我们将帧缓冲中屏幕显示的部分称为可视屏幕,将整个帧缓冲内存称为虚拟屏幕。

接着看一下在真彩色可视模式下描述位域的结构fb_bitfield,它的定义如下:

struct fb_bitfield {
    _u32 offset;    // 位域偏移
    _u32 length;    // 位域长度
    _u32 msb_right; // 不等于0时表示最高有效位在右边
};

最后,说一下像素时钟pixclock以及用它度量的那些时序单位。pixclock表示在屏幕上绘制一个像素所用的时间,单位时皮秒(10-12秒)。通常LCD规格书都有“DCLK Frequency”的时序参数,表示在屏幕上绘制点的时钟频率(DCLK是Dot Clock的缩写)。

此结构体成员还有height、width这两个成员,本来它们的作用是描述屏幕以毫米为单位度量的几何尺寸,但由于这两个参数在内核中并没有实际使用,驱动中往往把它们赋值为屏幕的像素尺寸(即与xres和yres相同)。

下面来看看fb_fix_screeninfo这个结构,它的定义如下:

 1 /* include/linux/fb.h */
 2 struct fb_fix_screeninfo {
 3     char id[16];    // 标识符
 4     unsigned long smem_start;    // fb缓冲内存的开始位置(物理地址)
 5
 6     __u32 smem_len;    // fb缓冲的长度
 7     __u32 type;    // FB_TYPE
 8     __u32 type_aux;    // Interleave
 9     __u32 visual;    // FB_VISUAL_*
10     __u16 xpanstep;    // 如果没有硬件panning 赋0
11     __u16 ypanstep;
12     __u16 ywrapstep;
13     __u32 line_length;    // 一行的字节数
14     unsigned long mmio_start;    // 内存映射I/O的开始位置
15
16     __u32 mmio_len;    // 内存映射I/O长度
17     __u32 accel;    // 保留
18
19     __u16 capabilities;
20     __u16 reserved[2];
21 };

(4)fb_cmap

fb_cmap结构体记录设备无关的颜色表信息,用户空间可以通过ioctl()命令FBIOGETCMAP和FBIOPUTCMAP读取和颜色表。

 1 /* include/linux/fb.h */
 2 struct fb_cmap {
 3     __u32 start;    // 第1个元素入口
 4     __u32 len;    // 元素数量
 5     /* R、G、B透明度 */
 6     __u16 *red;
 7     __u16 *green;
 8     __u16 *blue;
 9     __u16 *transp;
10 };

4  帧缓冲接口

(1)framebuffer_alloc()

framebuffer_alloc()分配一个fb_info结构内存。


头文件


#include <linux/fb.h>


函数原形


struct fb_info *framebuffer_alloc(size_t size, struct device *dev);


函数参数


size:指定了帧缓冲设备私有数据的大小


dev:指定控制器的父设备对象,通常为NULL


返回值


成功:返回指向fb_info结构的指针;失败:返回NULL

(2)register_framebuffer()

register_framebuffer()函数用于注册帧缓冲设备。


头文件


#include <linux/fb.h>


函数原形


int register_framebuffer(struct fb_info *fb_info);


函数参数


fb_info:帧缓冲设备结构


返回值


成功:返回0;失败:返回相应的错误码(负数)

(3)unregister_framebuffer()

unregister_framebuffer()函数用于注销帧缓冲设备。


头文件


#include <linux/fb.h>


函数原形


int unregister_framebuffer(struct fb_info *fb_info);


函数参数


fb_info:帧缓冲设备结构


返回值


成功:返回0;失败:返回相应的错误码(负数)

原文地址:https://www.cnblogs.com/laoyaodada/p/8398786.html

时间: 2024-08-02 05:47:14

帧缓冲子系统框架的相关文章

摄像头v4l2编写,实现视频在帧缓冲显示

申明:该文档只是记录我的编写和理解过程,代码部分参考了较多的文章,如有意见请联系我删除,谢谢. 目标: 使用v4l2提供API,完成摄像头视频采集,并使用帧缓存显示. 准备工作: USB摄像头1个 编译环境(我用的是PC+Ubuntu14.04) 了解大概情况,查看如下网址,基本情况应该没问题了:http://baike.baidu.com/item/V4L2?sefr=enterbtn 框架理解: 关键点理解: 摄像头采集的循环buf 必须使用循环buf,否则摄像头采集图像显示不会连续. 摄像

Linux输入子系统框架分析(1)

在Linux下的输入设备键盘.触摸屏.鼠标等都可以用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层,事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备驱动层将输入事件上报给核心层input.c,核心层找到匹配的事件层,将事件交给事件层处理,事件层处理完后传递到用户空间. 我们最终要搞清楚的是在用户空间调用open和read最终在内核中是怎样处理的,向内核上报的事件又是谁处理的,处理完后是怎样传递到用户空间的? 上面两个图是输入子系统的框架. 下面

OpenGL学习脚印: 帧缓冲对象(Frame Buffer Object)

写在前面 一直以来,我们在使用OpenGL渲染时,最终的目的地是默认的帧缓冲区,实际上OpenGL也允许我们创建自定义的帧缓冲区.使用自定义的帧缓冲区,可以实现镜面,离屏渲染,以及很酷的后处理效果.本节将学习帧缓存的使用,文中示例代码均可以在我的github下载. 本节内容整理自 1.OpenGL Frame Buffer Object (FBO) 2.www.learnopengl.com Framebuffers FBO概念 在OpenGL中,渲染管线中的顶点.纹理等经过一系列处理后,最终显

Linux驱动之输入子系统框架

    好记性不如烂笔头,整理一下笔记~ Linux驱动之输入子系统框架 输入子系统将该类驱动划分为3部分 1.核心层 input.c 2.设备层 Gpio_keys.c ... 3.事件处理层 Evdev.c 事件处理层为纯软件的东西,设备层涉及底层硬件,它们通过核心层建立联系,对外提供open write等接口. 1.我们首先来看,核心层 input.c如何向外界提供接口 在 input_init 中注册了字符设备驱动 register_chrdev(INPUT_MAJOR, "input&

帧缓冲设备应用开发

通过/dev/fbn,应用程序可进行的针对帧缓冲设备的操作主要有如下几种: 读写/dev/fbn:相当于读写屏幕缓冲区.例如cp /dev/fb0 tmp命令可将当前屏幕的内容复制到一个文件中,而命令cp tmp > /dev/fb0则将图形文件tmp显示在屏幕上. 映射操作:对于帧缓冲设备,可通过mmap()映射操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了. I/O控制:对于帧缓冲设备,对设备文件的ioctl()操作

输入子系统 框架

目录 回顾引入 简介 框架小结 次设备号 框架结构图 数据管理结构 关键函数 框架分析 input_init input_open_file input_register_handler input_register_device input_attach_handler connect read 程序设计 无框架驱动 框架架构 测试 hexdump分析 tty读取分析 按键连发 title: 输入子系统 框架 tags: linux date: 2018-11-28 15:39:22 toc:

V4L2捕捉画面+H264压缩视频+帧缓冲显示视频————帧缓冲显示视频

帧缓冲显示主要步骤 打开设备文件, 比如/dev/fb0 获取framebuffer的一些信息, 比如分辨率 设置参数 映射framebuffer内存到用户空间 写入要显示的画面 /* display.c */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd

input输入子系统框架分析

input子系统的搭建要点: 核心层为事件驱动层和设备驱动层的注册提供API的实现.核心层为设备驱动层上报事件提供API的实现 .事件驱动层为应用层提供API的实现 . (1)核心层:提供事件驱动层和设备驱动层所需的函数接口(为input dev和input handler建立联) drivers/input/input.c: ##主要接口函数一览:## ①为事件驱动层提供的: 注册API: int input_register_handler(struct input_handler *han

js--链式缓冲运动框架

这些框架都是鄙人自学的网上视频,至于是哪家,想必大家都知道的,当然不纠结这个,最主要的是学习的过程和结果,甚至于你理解,掌握了没有 网上有很多的开源框架,很佩服他们的思路和写法,或许这就是代码之美吧 我一个小小的前台,做界面的,现在也要去学习设计思路了,毕竟你拿工资的多少和你掌握技能的多少.深度是成正比的 当然更要相信 努力必有回报,坚持一定成功 以下是更新的学习运动框架的进度和代码 更新时间:2014-12-11 js框架---缓冲链式运动--已经掌握 1 //运动框架 2 //author: