转自:https://blog.csdn.net/linux_devices_driver/article/details/7079442

1、framebuffer 帧缓冲

    帧缓冲(framebuffer)是Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。

   
framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显存的一个映像,将其映射到进程空间后,就可以直接进行读写操作,写操作会直接反映在屏幕上。

    framebuffer是个字符设备,主设备号为29,对应于/dev/fb%d 设备文件。

通常,使用如下方式(前面的数字表示次设备号)
  0 = /dev/fb0 第一个fb 设备
  1 = /dev/fb1 第二个fb 设备

    fb
也是一种普通的内存设备,可以读写其内容。例如,屏幕抓屏:cp /dev/fb0 myfilefb
虽然可以像内存设备(/dev/mem)一样,对其read,write,seek 以及mmap。但区别在于fb
使用的不是整个内存区,而是显存部分。

2、fb与应用程序的交互

对于用户程序而言,它和其他的设备并没有什么区别,用户可以把fb看成是一块内存,既可以向内存中写数据,也可以读数据。fb的显示缓冲区位于内核空间,应用程序可以把此空间映射到自己的用户空间,在进行操作。

在应用程序中,操作/dev/fbn的一般步骤如下:
(1)打开/dev/fbn设备文件。
(2)用ioctl()操作取得当前显示屏幕的参数,如屏幕分辨率、每
个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。
(3)用mmap()函数,将屏幕缓冲区映射到用户空间。
(4)映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示了。

3、fb的结构及其相关结构体

在linux中,fb设备驱动的源码主要在Fb.h (linux2.6.28\include\linux)和Fbmem.c (linux2.6.28\drivers\video)两个文件中,它们是fb设备驱动的中间层,为上层提供系统调用,为底层驱动提供接口。

在fb.h文件中有fb驱动需要使用的很多结构,我们先对这些结构体进行说明:

(1)、

一个帧缓冲区对应一个struct fb_info结构,它包括了帧缓冲设备的属性和操作的完整集合,每个帧设备都有一个fb_info结构体。源码如下:

struct fb_info {
int node;
int flags;
struct mutex lock;/* Lock for open/release/ioctl funcs */互斥锁
struct fb_var_screeninfo var;/* Current var */当前缓冲区的可变参数
struct fb_fix_screeninfo fix;/* Current fix */固定参数
struct fb_monspecs monspecs;/* Current Monitor specs */当前显示器标志
struct work_struct queue;/* Framebuffer event queue */帧缓冲事件队列
struct fb_pixmap pixmap;/* Image hardware mapper */图像硬件mapper
struct fb_pixmap sprite;/* Cursor hardware mapper */光标硬件mapper
struct fb_cmap cmap;/* Current cmap */当前的调色板
struct list_head modelist;      /* mode list */
struct fb_videomode *mode;/* current mode */当前的视频模式

#ifdef CONFIG_FB_BACKLIGHT如果配置了LCD支持背光灯
/* 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 */fb设备
int class_flag;                    /* private sysfs flags */私有的sysfs标志
#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 */ ioremap的虚拟内存大小
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 */硬件的状态
void *fbcon_par;                /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
};

(2)、

/*
 * Frame buffer operations
 *
 * LOCKING NOTE: those functions must _ALL_ be called with the console
 * semaphore held, this is the only suitable locking mechanism we have
 * in 2.6. Some may be called at interrupt time at this point though.
 */
fb_ops结构体用来实现对帧缓冲设备的操作,这些函数需要驱动开发人员编写,

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);

这两个函数对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
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);

设置color寄存器的值
/* set color register */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
   unsigned blue, unsigned transp, struct fb_info *info);

批量设置color寄存器,设置颜色表
/* set color registers in batch */
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

显示空白
/* blank display */
int (*fb_blank)(int blank, struct fb_info *info);

pan显示
/* pan display */
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

填充矩形
/* Draws a rectangle */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);

            数据复制
/* Copy data from area to another */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);

           图形填充
/* Draws a image to the display */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

绘制光标
/* Draws cursor */
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

旋转显示
/* Rotates the display */
void (*fb_rotate)(struct fb_info *info, int angle);

等待blit空闲
/* wait for blit idle, optional */
int (*fb_sync)(struct fb_info *info);

fb特定的ioctl操作
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);

处理32兼容的ioctl操作
/* Handle 32bit compat ioctl (optional) */
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);

fb特定的mmap操作
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

保存目前的硬件状态
/* save current hardware state */
void (*fb_save_state)(struct fb_info *info);

恢复被保存的硬件状态
/* restore saved state */
void (*fb_restore_state)(struct fb_info *info);

通过fb_info获得framebuffer的能力
/* get capability given var */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
   struct fb_var_screeninfo *var);
};

(3)、

fb_fix_screeninfo结构体中,记录了用户不能修改的固定显示控制器参数。这些固定的参数如缓冲区的物理地址、缓冲区的长度等等。
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */

        字符串形式的标识符
unsigned long smem_start;/* Start of frame buffer mem */

/* (physical address) */

        fb缓存的开始位置
__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; /* see FB_VISUAL_* */

       屏幕使用的色彩模式 
__u16 xpanstep;/* zero if no hardware panning  */

        如果没有硬件panning ,赋0
__u16 ypanstep;/* zero if no hardware panning  */

__u16 ywrapstep;/* zero if no hardware ywrap    */

         1行的字节数
__u32 line_length;/* length of a line in bytes    */

         内存映射I/O的开始位置
unsigned long mmio_start;/* Start of Memory Mapped I/O   */
/* (physical address) */

         内存映射I/O的长度
__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 */
};

(4)、

fb_var_screeninfo结构体中存储了用户可以修改的显示器控制参数,例如屏幕分辨率、透明度等等。

struct fb_var_screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;

        可见解析度,即分辨率
__u32 xres_virtual;/* virtual resolution */
__u32 yres_virtual;

        虚拟解析度
__u32 xoffset;/* offset from virtual to visible */
__u32 yoffset;/* resolution */

虚拟到可见之间的偏移
__u32 bits_per_pixel;/* guess what */

        每像素位数,BPP
__u32 grayscale;/* != 0 Graylevels instead of colors */

        非0时指灰度

struct fb_bitfield red;/* bitfield in fb mem if true color, */
struct fb_bitfield green;/* else only length is significant */
struct fb_bitfield blue;

         fb缓存的R\G\B位域
struct fb_bitfield transp;/* transparency */

         透明度

__u32 nonstd; /* != 0 Non standard pixel format */

        != 0 非标准像素格式

__u32 activate;/* see FB_ACTIVATE_* */

       
__u32 height; /* height of picture in mm    */

         屏幕的高度
__u32 width; /* width of picture in mm     */

屏幕的宽度
__u32 accel_flags;/* (OBSOLETE) see fb_info.flags */
         fb_info的标志

/* 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_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */

        顺时钟旋转的角度
__u32 reserved[5];/* Reserved for future compatibility */
};

(5)、

fb_cmap结构体中记录了颜色板信息,即调色板信息。,用户空间可以通过ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令读取或设定颜色表。

struct fb_cmap {
__u32 start; /* First entry */第一个元素的入口
__u32 len; /* Number of entries */元素个数
__u16 *red; /* Red values */红色、绿色、蓝色
__u16 *green;  
__u16 *blue;
__u16 *transp;/* transparency, can be NULL */透明度
};

 

上面这些结构体之间有什么关系呢?看下图:


 

(6)、

fb_bitfield 结构体描述每一像素显示缓冲区的组织方式,包含位域偏移、位域长度和MSB 指示,

struct fb_bitfield {
__u32 offset; /* beginning of bitfield */

         位域偏移
__u32 length; /* length of bitfield */

        位域长度
__u32 msb_right;/* != 0 : Most significant bit is */ 
/* right */

        MSB
};

Linux中LCD设备驱动-framebuffer(帧缓冲)【】的更多相关文章

  1. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

  2. linux中MTDflash设备驱动大概

    一.主要结构体 1.mtd_info,主要是描述MTD原始设备层中的设备或分区, 2.mtd_part,表示一个分区,用里面的主mtd_info和本分区mtd_info描述分区, 3.mtd_part ...

  3. linux lcd设备驱动剖析四

    在"linux lcd设备驱动剖析二"文章中,我们详细分析了s3c24xxfb_probe函数. 文章链接:http://blog.csdn.net/lwj103862095/ar ...

  4. linux lcd设备驱动剖析一

    s3c2440 lcd驱动源码文件是:drivers/video/s3c2410fb.c 看驱动源码首先当然是先看入口函数,这里是s3c2410fb_init函数 [cpp] view plain? ...

  5. Linux和Windows设备驱动架构比较

    毕业后一直在学操作系统, 有时候觉得什么都懂了,有时候又觉得好像什么都不懂,但总体来说自认为对操作系统实现机制的了解比周围的人还是要多一些.去年曾花了几个星期的晚上时间断断续续翻译了这篇对Linux和 ...

  6. 芯灵思SinlinxA33开发板 Linux平台总线设备驱动

    1.什么是platform(平台)总线? 相对于USB.PCI.I2C.SPI等物理总线来说,platform总线是一种虚拟.抽象出来的总线,实际中并不存在这样的总线. 那为什么需要platform总 ...

  7. Linux下 USB设备驱动分析(原创)

    之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...

  8. Linux的总线设备驱动模型

    裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...

  9. linux lcd设备驱动剖析三

    上一节文章中详细地剖析了probe函数,但是从始至终都没有看到打开读写文件接口的操作函数,只看到了下面这个操作结构体 [cpp] view plain? static struct fb_ops s3 ...

随机推荐

  1. 一个CSS简单入门网站

    讲的知识简单明了,很实用: http://zh.learnlayout.com/

  2. C++高效安全的运行时动态类型转换

    关键字:static_cast,dynamic_cast,fast_dynamic_cast,VS 2015. OS:Window 10. C++类之间类型转换有:static_cast.dynami ...

  3. [Android]上传到多个Maven仓库的Gradle插件RapidMavenPushPlugin

    博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml RapidMavenPushPlugin 用 ...

  4. day-5 python协程与I/O编程深入浅出

    基于python编程语言环境,重新学习了一遍操作系统IO编程基本知识,同时也学习了什么是协程,通过实际编程,了解进程+协程的优势. 一.python协程编程实现 1.  什么是协程(以下内容来自维基百 ...

  5. vmware 12 安装 mac os 10.12正式版

    1.首先下载安装vmware 12 pro ,将VT打开(虚拟功能,以前安装过虚拟机点的同学可忽略). 2.下载mac ox 10.12正式版镜像文件(cdr后缀). 3.下载Unlocker208( ...

  6. 使用 dynamic 类型让 ASP.NET Core 实现 HATEOAS 结构的 RESTtful API

    上一篇写的是使用静态基类方法的实现步骤:  http://www.cnblogs.com/cgzl/p/8726805.html 使用dynamic (ExpandoObject)的好处就是可以动态组 ...

  7. LXC学习实践(2)安装LXC

    1.准备工作: yum install gcc yum install libcap-devel yum install libcgroup 2.安装LXC 下载源代码:sourceforge.net ...

  8. hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(3)http://www.cnblogs.com/liugh/p/6624491.html

    一.文件准备 scala-2.12.1.tgz 下载地址: http://www.scala-lang.org/download/2.12.1.html 二.工具准备 2.1 Xshell 2.2 X ...

  9. python入门(9)字符串和编码

    python入门(9)字符串和编码 字符串是一种数据类型,比较特殊的是字符串有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理. 最早的计算机在设计时采用8个比 ...

  10. 京东2019春招Java工程师编程题题解

    生成回文串 题目描述 对于一个字符串,从前开始读和从后开始读是一样的,我们就称这个字符串是回文串. 例如"ABCBA","AA","A"是回 ...