Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1246458
  • 博文数量: 105
  • 博客积分: 127
  • 博客等级: 入伍新兵
  • 技术积分: 962
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-29 15:22
文章分类

全部博文(105)

文章存档

2021年(1)

2019年(3)

2018年(1)

2017年(11)

2016年(47)

2015年(32)

2014年(4)

2012年(6)

我的朋友

分类: LINUX

2012-11-28 09:08:45

       Linux 字符类设备驱动,很大一部分代码都是相同的,具有一些共性。内核工作者,总是考虑得那么全面。MISC驱动模型就简化了一类字设备符驱动。MISC 其主设备号为10,次设备号则是由驱动开发者来分配。当然有些次设备号也是已经被使用了。可以查看源码下面的Documentation/devices.txt 。字符设备的流程不再赘言。直接先看看用MISC模型的字符驱动流程。

 

从这个流程可以看出来,MISC字符设备驱动很简单。当然这个简单是由内于核来完成了一部分工作,才变得如此清晰。

  MISC模型有关的文件:

drivers/char/misc.c     模型建立。实现了面向用户的接口函数misc_register ,misc_deregister

                                 proc文件实现等。

include/linux/miscdevice.h    函数申明以及一些结构体。

 

点击(此处)折叠或打开

  1. struct miscdevice {
  2.     int minor; // 次设备号
  3.     const char *name; //设备名
  4.     const struct file_operations *fops; //字符设备fops
  5.     struct list_head list;                //内核有misc list链表
  6.     struct device *parent; //这两个设备结构体是为了创建设备文件
  7.     struct device *this_device; //
  8.     const char *devnode;            
  9. };

 

从流程图中看不出有任何字符设备的痕迹。看看如何封装的。在misc.cmisc_init这个就是MISC驱动模型的入口。

 

   从上面图中可以知道,字符设备的那一套在misc_init中实现了。

 

misc_register()

 

点击(此处)折叠或打开

  1. int misc_register(struct miscdevice * misc)
  2. {
  3.     struct miscdevice *c;
  4.     dev_t dev;
  5.     int err = 0;
  6.   
  7.   
  8.     INIT_LIST_HEAD(&misc->list); //链表项使用时必须初始化
  9.   
  10.     
  11.      mutex_lock(&misc_mtx);
  12.      list_for_each_entry(c, &misc_list, list) {
  13.      if (c->minor == misc->minor) {
  14.      mutex_unlock(&misc_mtx);
  15.      return -EBUSY;
  16.      }
  17.      } //遍历链表如果发现次设备号一样的,返回错误
  18.     
  19.     
  20.      if (misc->minor == MISC_DYNAMIC_MINOR) { //动态次设备号
  21.      int i = DYNAMIC_MINORS;
  22.      while (--i >= 0)
  23.      if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
  24.      break;
  25.      if (i<0) {
  26.      mutex_unlock(&misc_mtx);
  27.      return -EBUSY;
  28.      }
  29.      misc->minor = i;
  30.      }
  31.     
  32.     
  33.      if (misc->minor < DYNAMIC_MINORS)
  34.      misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
  35.      dev = MKDEV(MISC_MAJOR, misc->minor);
  36.     
  37.      //创建了设备节点,所有的misc设备都是基于misc_class这个类的,仅次设备号就可以
  38.      //              创建区别于其他misc设备的设备节点        
  39.      misc->this_device = device_create(misc_class, misc->parent, dev,
  40.      misc, "%s", misc->name);
  41.      //udev创建设备节点使用,linux设备模型相关
  42.      if (IS_ERR(misc->this_device)) {
  43.      err = PTR_ERR(misc->this_device);
  44.      goto out;
  45.      }
  46.     
  47.     
  48.      /*
  49.      * Add it to the front, so that later devices can "override"
  50.      * earlier defaults
  51.      */
  52.      list_add(&misc->list, &misc_list); //添加到misc_list之中
  53.      out:
  54.      mutex_unlock(&misc_mtx);
  55.      return err;
  56.     }

首先遍历misc_list链表,查找所用的次设备号是否已经被注册,防止冲突。如果是动态次设备号则分配一个,然后调用MKDEV生成设备号,从这里可以看出所有的misc设备共享一个主设备号MISC_MAJOR,然后调用device_create,生成设备文件,这里就用到了misc_init中的class_create创建的类。最后将此注册的设备驱动中的list加入到misc_list链表中。

misc_deregister 中与misc_register中刚好是相反的工作。在misc_list 链表中删除此list device_destroy 删除设备文件。MISC模型大概就是这样的。

参考资料:http://blog.csdn.net/yaozhenguo2006/article/details/6760575

阅读(8972) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~