所有的misc设备驱动的主设备号都为10,不同的设备使用不同的从设备号。当使用misc设备驱动时,misc设备会自动创建cdev,不用像以前一样需要手动创建,因此采用misc设备驱动可以简化字符设备驱动的编写。
misc设备用miscdevice结构体表示,具体定义在include/linux/miscdevice.h 中,内容如下:
57 struct miscdevice {
58 int minor; /* 子设备号 */
59 const char *name; /* 设备名字 */
60 const struct file_operations *fops; /* 设备操作集 */
61 struct list_head list;
62 struct device *parent;
63 struct device *this_device;
64 const struct attribute_group **groups;
65 const char *nodename;
66 umode_t mode;
67 };
当我们创建一个misc设备的miscdevice结构体时,需要我们指定minor、name和fops这三个成员变量。minor表示子设备号,需要用户设置,在Linux内核中有一些预定义的misc设备的子设备号,定义在include/linux/miscdevice.h 文件中,如下所示:
13 #define PSMOUSE_MINOR 1
14 #define MS_BUSMOUSE_MINOR 2 /* unused */
15 #define ATIXL_BUSMOUSE_MINOR 3 /* unused */
16 /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */
17 #define ATARIMOUSE_MINOR 5 /* unused */
18 #define SUN_MOUSE_MINOR 6 /* unused */
......
52 #define MISC_DYNAMIC_MINOR 255
我们设置子设备号时要注意不要重复使用其他设备的子设备号。可以从这些预定义的子设备号中选择一个,也可以自定义。
name就是这个misc设备的名字,当设备注册成功后,会在/dev目录下自动生成一个名为name的设备文件。fops就是这个misc设备的操作集合。
当创建好miscdevice结构体后,使用misc_register 函数向系统中注册一个misc设备,函数原型如下:
int misc_register(struct miscdevice * misc)
参数misc就是之前创建好的miscdevice结构体。成功返回0,失败返回负数。
在创建字符设备驱动时,我们会使用下面几个函数完成设备的创建:
1 alloc_chrdev_region(); /* 申请设备号 */
2 cdev_init(); /* 初始化 cdev */
3 cdev_add(); /* 添加 cdev */
4 class_create(); /* 创建类 */
5 device_create(); /* 创建设备 */
现在只需要一个misc_register 函数就可以替代上面这几个函数。
在设备驱动的卸载函数中,使用misc_deregister 函数来注销掉misc设备。函数原型如下:
int misc_deregister(struct miscdevice *misc)
参数misc就是要注销的miscdevice结构体。
同样的misc_deregister 函数用来代替下面这几个字符设备的注销函数:
1 cdev_del(); /* 删除 cdev */
2 unregister_chrdev_region(); /* 注销设备号 */
3 device_destroy(); /* 删除设备 */
4 class_destroy(); /* 删除类 */