Linux包含了许多的设备驱动类型,而不管分类有多细,总会有些漏网的,这就是我们经常说到的“其他的”等等。
在Linux里面,把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体来描述)。Linux/内核所提供的miscdevice有很强的包容性。如NVRAM,看门狗,DS1286等实时时钟,字符LCD,AMD 768随机数发生器。
      miscdevice共享一个主设备号MISC_MAJOR(10),但此设备号不同,所有的miscdevice设备形成一个链表,对设备访问时内核根据次设备号查找对应的 miscdevice设备,然后调用其中的file_operations结构体中注册的文件操作接口进程操作。
     
struct miscdevice  {
 int minor;
 const char *name;
 const struct file_operations *fops;
 struct list_head list;
 struct device *parent;
 struct device *this_device;
};

miscdevice 在本质上任然是字符设备,只是被增加了以层封装而已,因此其驱动的主体工作还是file_operations的成员函数。
对于miscdevice 的注册和注销分别通过如下两个API完成:
int misc_register(struct miscdevice *misc)
int misc_deregister(struct miscdevice *misc)

/*misc设备注册的时候发生了什么?*/
------------------------------------------------------------------------
misc_register(&led_misc);
 /*1.给我们寻找一个次设备号*/
 if (misc->minor == MISC_DYNAMIC_MINOR) {
  int i = DYNAMIC_MINORS;
  while (--i >= 0)
   if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
    break;
  if (i<0) {
   mutex_unlock(&misc_mtx);
   return -EBUSY;
  }
  misc->minor = i;
 }
 if (misc->minor < DYNAMIC_MINORS)
  misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
 /*2.加入到链表中*/
 list_add(&misc->list, &misc_list);


/*misc设备向上注册字符设备驱动的过程*/
-----------------------------------------------------------------------------
static int __init misc_init(void)
 misc_class = class_create(THIS_MODULE, "misc");
 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))    /*向内核注册字符设备驱动*/


关于misc_fops结构体:
------------------------------------------------------------------------------
static const struct file_operations misc_fops = {
 .owner  = THIS_MODULE,
 .open  = misc_open,
};


/*打开misc设备的时候发生了什么事情*/
------------------------------------------------------------------------------
static int misc_open(struct inode * inode, struct file * file)
  int minor = iminor(inode);  /*获取次设备号*/

Logo

更多推荐