IT技术互动交流平台

源码分析Fbmem.c之LCD驱动

作者:小聊  发布日期:2013-05-21 11:44:04

一、前言

之前已经分析过了framebuffer设备驱动的加载与卸载,那么究竟用户层是怎么与Kernel交互的呢?也就是说怎么进行图像传输的。LCD的系统架构图很好的说明了这一切,因此定位到fbmem.c。


 

二、代码分析

1、在sprdfb_main.c文件中注册了帧缓冲设备


  ret = register_framebuffer(fb);

2、register_framebuffer函数中registered_fb[i] = fb_info;初始化了一个全局的fb_info。

3、Kernel初始化时对fbmem进行了初始化

 

static int __init fbmem_init(void)
{
      proc_create("fb", 0, NULL, &fb_proc_fops);
 
      if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
           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; }

a、这里在proc文件夹下了创建了一个设备文件,用来提供系统中有关进程的信息;

b、注册字符设备,提供fb设备的操作方式,

c、创建类

4、fb_ops成员函数如下:

 

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

为用户提供了读写、控制、映射、打开和关闭。www.it165.net

5、用户一开始需要打开fb设备,对应于fb_open

 

static int
fb_open(struct inode *inode, struct file *file)
__acquires(&info->lock)
__releases(&info->lock)
{
      int fbidx = iminor(inode);
      struct fb_info *info;
      int res = 0;
 
      if (fbidx >= FB_MAX)
           return -ENODEV;
      info = registered_fb[fbidx];
      if (!info)
           request_module("fb%d", fbidx);
      info = registered_fb[fbidx];
      if (!info)
           return -ENODEV;
      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);
      return res;
}

info = registered_fb[fbidx];获取了帧缓冲设备注册时的fb_info,也就是sprdfb_main.c中注册的fb_info信息。

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

7、read write ioctl这里就不再深入介绍,有兴趣可以看源代码。

 

三、总结

用户打开fb总体流程如下图所示


 
 
Tag标签: 源码   Fbmem   LCD驱动  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规