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

fbmem.c中实现了对framebuffer的共性的抽象,lcd驱动其实就是设置lcd控制器的工作方式,然后对显存进行读写,对显存的操作其实不管什么lcd,都是差不多的,所以这些相似的操作都抽取到了内核的fbmem.c里面,实现驱动的时候只需要填fb_info结构体,把lcd硬件相关的参数填入该结构体中,然后用register_framebuffer函数进行注册,该函数会自动生成设备节点,就是/dev/fb0,/dev/fb1 等等,对于显存的读写函数就用内核已经实现的默认的cfb_fillrect, cfb_copyarea, cfb_imageblit即可,其实不用自己去做实现,对于简单的lcd显示操作而言已经足够了

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

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

LCD核心层fbmem.c给上层提供接口调用
file_operations fb_fops = {
.read = fb_read,
.write = fb_write,
.unlocked_ioctl = fb_ioctl,
.open = fb_open,
}
||---------------------------------------------||
|| 调用下面的具体framebuffer驱动
||---------------------------------------------||

LCD具体framebuffer驱动:(drivers/video/xxfb.c,如mtk的mtkfb.c)
1、实现fb_info结构体
(1)分配一个fb_info 结构
(2)设置里边的成员:LCD可变参数、LCD固定参数、显存基地址、操作函数。
(3)注册fb_info: 用函数register_framebuffer(),函数具体在fbmem.c中实现;

2、 硬件相关的初始化:
GPIO配置成LCD引脚、时序极性等。


代码分析:

1、 在 xxxfb.c(例如mtk平台的mtkfb.c)文件中注册了帧缓冲设备
r = register_framebuffer(fbi);

2、 register_framebuffer函数中registered_fb[i] = fb_info;初始化了一个全局的fb_info。
具体调用如下:
mtkfb_probe
==> r = register_framebuffer(fbi) //mtkfb.c文件中
==> int register_framebuffer(struct fb_info *fb_info) //fbmem.c
==> ret = do_register_framebuffer(fb_info); //fbmem.c
==> registered_fb[i] = fb_info; //fbmem.c

3、 Kernel初始化时对fbmem进行了初始化(fbmem.c文件中)

static int __init fbmem_init(void)
{
proc_create(“fb”, 0, NULL, &fb_proc_fops); //在proc文件夹下了创建了一个设备文件fb,用来提供系统中有关进程的信息;

if (register_chrdev(FB_MAJOR,“fb”,&fb_fops)) //注册字符设备,提供fb设备的操作方式
printk(“unable to get major %d for fb devs\n”, FB_MAJOR);

fb_class = class_create(THIS_MODULE, “graphics”); //创建类
if (IS_ERR(fb_class)) {
printk(KERN_WARNING “Unable to create fb class; errno = %ld\n”, PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}

4、 fb_fops 成员函数如下:为用户提供了读写、控制、映射、打开和关闭等函数调用。(fbmem.c文件中)
static const struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read, //读
.write = fb_write,
.unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = fb_compat_ioctl,
#endif
.mmap = fb_mmap,
.open = fb_open,
.release = fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
#endif
.llseek = default_llseek,
};

5、 用户一开始需要打开fb设备,对应于 fb_open函数 (fbmem.c文件中)

static int
fb_open(struct inode *inode, struct file *file)
__acquires(&info->lock)
__releases(&info->lock)
{
int fbidx = iminor(inode); //取出设备次设备号
struct fb_info *info; //定义了一个fb_info结构
int res = 0;

info = get_fb_info(fbidx); //在次设备里面得到fb_info结构信息赋值给info
if (!info) {
request_module(“fb%d”, fbidx);
info = get_fb_info(fbidx);
if (!info)
return -ENODEV;
}
if (IS_ERR(info))
return PTR_ERR(info);

mutex_lock(&info->lock);
if (!try_module_get(info->fbops->owner)) {
res = -ENODEV;
goto out;
}
file->private_data = info;
if (info->fbops->fb_open) {
res = info->fbops->fb_open(info,1);
if (res)
module_put(info->fbops->owner);
}
#ifdef CONFIG_FB_DEFERRED_IO
if (info->fbdefio)
fb_deferred_io_open(info, inode, file);
#endif
out:
mutex_unlock(&info->lock);
if (res)
put_fb_info(info);
return res;
}

6、用ioctl()操作取得当前显示屏幕的参数,如屏幕分辨率、每个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。

7、 打开之后,用户就可以通过映射mmap,将显示缓冲区映射到用户空间,从而使得用户空间可以直接操作显示缓冲区,而省去一次用户空间到内核空间的内存复制过程。

8、 显示图像到LCD设备就相当于往帧缓冲区中写入数据,获取LCD设备上的图像就相当于拷贝帧缓冲区中的数据(读操作),具体可以看源代码(fbmem.c文件中)。

用户打开fb总体流程如下图所示(图片来自网上):

linux中LCD之framebuffer设备驱动相关推荐

  1. Linux内核学习-字符设备驱动学习(二)

    在Linux内核学习-字符设备驱动学习(一)中编写字符设备驱动的一种方法,但是需要手动创建设备节点. 有没有能够自动的创建设备节点的呢? 有!使用class_create()和device_creat ...

  2. 一起分析Linux系统设计思想——05字符设备驱动框架剖析(四)

    在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习.我的使命就是过滤掉大量的垃圾信息,将知识体系化,以短平快的方式直 ...

  3. linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)

    最近工作中又使用到了I2C,所以借S3C2440开发板GT2440为硬件平台温习一遍I2C驱动体系. linux内核中IIC驱动的体系框架 linux内核中IIC部分驱动代码位于:/drivers/i ...

  4. Linux I2C子系统分析-I2C设备驱动

    接下来以一个实际的例子来看I2C设备驱动,就以drivers/i2c/i2c-dev.c为例. 先看它的初始化和注销函数 [cpp] view plaincopy static int __init  ...

  5. linux内核组件分析之--设备驱动模型之bus

    前面我们分析了设备驱动模型中的device和driver,device和driver本来是不相关的东西,只因为bus的存在,才被联系到了一起.本节就来看看设备驱动模型中起枢纽作用的bus.本节的头文件 ...

  6. linux内核部件分析之——设备驱动模型之class

    前面看过了设备驱动模型中的bus.device.driver,这三种都是有迹可循的.其中bus代表实际的总线,device代表实际的设备和接口,而driver则对应存在的驱动.但本节要介绍的class ...

  7. linux misc device字符杂项设备驱动

    杂项设备也是在嵌入式系统中用得比较多的一种设备驱动.miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同.misc设备其实就是特殊的字符设备,主设备编号采用10,并且可自 ...

  8. linux内核部件分析(十)——设备驱动模型之class,linux内核部件分析(十)——设备驱动模型之class...

    前面看过了设备驱动模型中的bus.device.driver,这三种都是有迹可循的.其中bus代表实际的总线,device代表实际的设备和接口,而driver则对应存在的驱动.但本节要介绍的class ...

  9. Linux内核自带SPI设备驱动测试程序分析:spidev_test.c

        在Linux系统中,SPI 的用户模式设备接口的驱动源码位于 drivers/spi/spidev.c,在应用层生成 /dev/spidev* 的节点,可以通过 read. write 达到与 ...

  10. linux内核模块编程(六)----字符设备驱动中断开发

    先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题 一 why 字符设备驱动在我们 ...

最新文章

  1. Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析--csdn 曹胜欢...
  2. linux java 替换jre_Linux系统 无需JRE配置Java
  3. Xcode 9“ iPhone忙:准备对iPhone的调试器支持”
  4. boost::mp11::mp_inherit相关用法的测试程序
  5. MTU 设置错误导致防火墙或者路由器断网
  6. Thymeleaf的Spring数据
  7. cmake 构建路径_基于CMake构建系统的MLIR Example扩展
  8. SQL Server存储过程中使用表值作为输入参数示例
  9. 如何在计算机自动开机时选择用户,电脑如何设置自动开机,详细教您如何设置...
  10. google三篇重要论文(英文原文)
  11. java applepay_java后端处理Apple Pay流程
  12. Python-Django毕业设计小斌美食网站(程序+LW)
  13. JS基础-事件模型(事件事件流自定义事件事件冒泡/代理)
  14. 海康摄像头的ISAPI协议
  15. 视觉软件工程师具体的工作内容是什么?
  16. 项目开发安全经验总结
  17. oracle中制表符,oracle中去掉文本中的换行符、回车符、制表符
  18. 由人眼追踪技术想到的
  19. Pycharm社区版下载与安装教程
  20. 拓扑排序基本题目(一) OpenJ_Bailian - 4084

热门文章

  1. Allegro画焊盘
  2. ASP.NET 使用Session,避免用户F5刷新时重复提交(转)
  3. iOS 四种延时的方法
  4. C/C++怎样传递二维数组,转载自CSDN
  5. 网页下载CAB文件总结
  6. 多模态中预训练的演变史
  7. TextCNN可以和对比学习融合吗-SimCSE论文读后感
  8. 【NLP】用腻了 CRF,试试 LAN 吧?
  9. 资源 | 我拿到了斯坦福、UCL、CMU、NYU的offer,关于博士申请你需要知道的一切...
  10. 论文赏析[ACL18]基于RNN和动态规划的线性时间成分句法分析