杂项设备(misc device)

杂项设备(misc device)
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动。在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc device从设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号10 ,一起归于misc device,其实misc_register就是用主标号10调用register_chrdev()的。
也就是说,misc设备其实也就是特殊的字符设备。
字符设备(char device)
使用register_chrdev(LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱动程序时,如果有多个设备使用该函数注册驱动程序,LED_MAJOR不能相同,否则几个设备都无法注册(我已验证)。如果模块使用该方式注册并且 LED_MAJOR为0(自动分配主设备号 ),使用insmod命令加载模块时会在终端显示分配的主设备号和次设备号,在/dev目录下建立该节点,比如设备leds,如果加载该模块时分配的主设备号和次设备号为253和0,则建立节点:mknod leds c 253 0。使用register_chrdev (LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱动程序时都要手动建立节点 ,否则在应用程序无法打开该设备。

mise device在linux内核源码中的定义如下:

         #ifndef _LINUX_MISCDEVICE_H     
  1. 02.#define _LINUX_MISCDEVICE_H     
  2. 03.#include <linux/module.h>     
  3. 04.#include <linux/major.h>     
  4. 05.    
  5. 06.#define PSMOUSE_MINOR       1     
  6. 07.#define MS_BUSMOUSE_MINOR   2     
  7. 08.#define ATIXL_BUSMOUSE_MINOR    3     
  8. 09./*#define AMIGAMOUSE_MINOR  4   FIXME OBSOLETE */    
  9. 10.#define ATARIMOUSE_MINOR    5     
  10. 11.#define SUN_MOUSE_MINOR     6     
  11. 12.#define APOLLO_MOUSE_MINOR  7     
  12. 13.#define PC110PAD_MINOR      9     
  13. 14./*#define ADB_MOUSE_MINOR   10  FIXME OBSOLETE */    
  14. 15.#define WATCHDOG_MINOR      130 /* Watchdog timer     */     
  15. 16.#define TEMP_MINOR      131 /* Temperature Sensor */     
  16. 17.#define RTC_MINOR       135     
  17. 18.#define EFI_RTC_MINOR       136 /* EFI Time services */     
  18. 19.#define SUN_OPENPROM_MINOR  139     
  19. 20.#define DMAPI_MINOR     140 /* DMAPI */     
  20. 21.#define NVRAM_MINOR     144     
  21. 22.#define SGI_MMTIMER     153     
  22. 23.#define STORE_QUEUE_MINOR   155     
  23. 24.#define I2O_MINOR       166     
  24. 25.#define MICROCODE_MINOR     184     
  25. 26.#define TUN_MINOR       200     
  26. 27.#define MWAVE_MINOR     219 /* ACP/Mwave Modem */     
  27. 28.#define MPT_MINOR       220     
  28. 29.#define HPET_MINOR      228     
  29. 30.#define FUSE_MINOR      229     
  30. 31.#define KVM_MINOR       232     
  31. 32.#define MISC_DYNAMIC_MINOR  255     
  32. 33.    
  33. 34.struct device;     
  34. 35.    
  35. 36.struct miscdevice  {     
  36. 37.    int minor;     
  37. 38.    const char *name;     
  38. 39.    const struct file_operations *fops;     
  39. 40.    struct list_head list;     
  40. 41.    struct device *parent;     
  41. 42.    struct device *this_device;     
  42. 43.};     
  43. 44.    
  44. 45.extern int misc_register(struct miscdevice * misc);     
  45. 46.extern int misc_deregister(struct miscdevice *misc);     
  46. 47.    
  47. 48.#define MODULE_ALIAS_MISCDEV(minor)             /     
  48. 49.    MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR)  /     
  49. 50.    "-" __stringify(minor))     
  50. 51.#endif    

 

 

在Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述)。miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同。 所有的miscdevice设备形成了一个链表,对设备访问时内核根据次设备号查找对应的miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。 在内核中用struct miscdevice表示miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。miscdevice的API实现在drivers/char/misc.c中。

下边是描述这个设备的结构体:

1.struct miscdevice  {      
2.    int minor;                               //次设备号   
3.    const char *name;                        //设备的名称      
4.    const struct file_operations *fops;     //文件操作    
5.    struct list_head list;                  //misc_list的链表头  
6.    struct device *parent;                  //父设备(Linux设备模型中的东东了,哈哈)      
7.    struct device *this_device;             //当前设备,是device_create的返回值,下边会看到  
8.}; 
然后来看看misc子系统的初始化函数:

1.static int __init misc_init(void)   
2.{   
3.    int err;   
4.  
5.#ifdef CONFIG_PROC_FS   
6.    /*创建一个proc入口项*/  
7.    proc_create("misc", 0, NULL, &misc_proc_fops);                   
8.#endif   
9.    /*在/sys/class/目录下创建一个名为misc的类*/  
10.    misc_class = class_create(THIS_MODULE, "misc");   
11.    err = PTR_ERR(misc_class);   
12.    if (IS_ERR(misc_class))   
13.        goto fail_remove;   
14.   
15.    err = -EIO;  
16.    /*注册设备,其中设备的主设备号为MISC_MAJOR,为10。设备名为misc,misc_fops是操作函数的集合*/   
17.    if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))   
18.        goto fail_printk;   
19.    return 0;   
20.   
21.fail_printk:   
22.    printk("unable to get major %d for misc devices/n", MISC_MAJOR);   
23.    class_destroy(misc_class);   
24.fail_remove:   
25.    remove_proc_entry("misc", NULL);   
26.    return err;   
27.}   
28./*misc作为一个子系统被注册到linux内核中*/  
29.subsys_initcall(misc_init);  
下边是register_chrdev函数的实现:

1.int register_chrdev(unsigned int major, const char *name,  
2.            const struct file_operations *fops)  
3.{  
4.    struct char_device_struct *cd;  
5.    struct cdev *cdev;  
6.    char *s;  
7.    int err = -ENOMEM;  
8.    /*主设备号是10,次设备号为从0开始,分配256个设备*/  
9.    cd = __register_chrdev_region(major, 0, 256, name);  
10.    if (IS_ERR(cd))  
11.        return PTR_ERR(cd);  
12.    /*分配字符设备*/  
13.    cdev = cdev_alloc();  
14.    if (!cdev)  
15.        goto out2;  
16.  
17.    cdev->owner = fops->owner;  
18.    cdev->ops = fops;  
19.    /*Linux设备模型中的,设置kobject的名字*/  
20.    kobject_set_name(&cdev->kobj, "%s", name);  
21.    for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/'))  
22.        *s = '!';  
23.    /*把这个字符设备注册到系统中*/     
24.    err = cdev_add(cdev, MKDEV(cd->major, 0), 256);  
25.    if (err)  
26.        goto out;  
27.  
28.    cd->cdev = cdev;  
29.  
30.    return major ? 0 : cd->major;  
31.out:  
32.    kobject_put(&cdev->kobj);  
33.out2:  
34.    kfree(__unregister_chrdev_region(cd->major, 0, 256));  
35.    return err;  
36.} 

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2012-05/60856.htm

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值