杂项设备也是在嵌入式系统中用得比较多的一种设备驱动。在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc device从设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号10 ,一起归于misc device,其实misc_register就是用主标号10调用register_chrdev()的。也就是说,misc设备其实也就是特殊的字符设备,可自动生成设备节点。
\include\linux\miscdevice.h
在这个头文件中主要是misc(混合)设备注册和注销:
其它类型---不能严格划分的设备类型,也叫混合类型
有:
- #ifndef _LINUX_MISCDEVICE_H
- #define _LINUX_MISCDEVICE_H
- #include <linux/module.h>
- #include <linux/major.h>
- #define PSMOUSE_MINOR 1
- #define MS_BUSMOUSE_MINOR 2
- #define ATIXL_BUSMOUSE_MINOR 3
- /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */
- #define ATARIMOUSE_MINOR 5
- #define SUN_MOUSE_MINOR 6
- #define APOLLO_MOUSE_MINOR 7
- #define PC110PAD_MINOR 9
- /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
- #define WATCHDOG_MINOR 130 /* Watchdog timer */
- #define TEMP_MINOR 131 /* Temperature Sensor */
- #define RTC_MINOR 135
- #define EFI_RTC_MINOR 136 /* EFI Time services */
- #define SUN_OPENPROM_MINOR 139
- #define DMAPI_MINOR 140 /* DMAPI */
- #define NVRAM_MINOR 144
- #define SGI_MMTIMER 153
- #define STORE_QUEUE_MINOR 155
- #define I2O_MINOR 166
- #define MICROCODE_MINOR 184
- #define TUN_MINOR 200
- #define MWAVE_MINOR 219 /* ACP/Mwave Modem */
- #define MPT_MINOR 220
- #define MPT2SAS_MINOR 221
- #define HPET_MINOR 228
- #define FUSE_MINOR 229
- #define KVM_MINOR 232
- #define MISC_DYNAMIC_MINOR 255
- struct device;
- struct miscdevice {
- int minor;/*次设备号*/
- const char *name;/*misc设备名*/
- const struct file_operations *fops;/*misc设备文件操作结构体*/
- struct list_head list;
- struct device *parent;
- struct device *this_device;
- const char *nodename;
- mode_t mode;
- };
minor:所有的misc设备共用一个主设备号,所以注册misc设备时只要次
设备号就可以了。利用次设备号来区分设备的。
misc设备注册:
extern int misc_register(struct miscdevice * misc);
misc设备注销:
extern int misc_deregister(struct miscdevice * misc);
drivers/char/misc.c
- int misc_register(struct miscdevice * misc)
- {
- struct miscdevice *c;
- dev_t dev;
- int err = 0;
- down(&misc_sem);
- list_for_each_entry(c, &misc_list, list) {
- if (c->minor == misc->minor) {
- up(&misc_sem);
- return -EBUSY;
- }
- }
- 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) {
- up(&misc_sem);
- return -EBUSY;
- }
- misc->minor = i;
- }
- if (misc->minor < DYNAMIC_MINORS)
- misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
- dev = MKDEV(MISC_MAJOR, misc->minor);
-
- misc->class = class_device_create(misc_class, NULL, dev, misc->dev,"%s", misc->name);
- if (IS_ERR(misc->class)) {
- err = PTR_ERR(misc->class);
- goto out;
- }
- /*
- * Add it to the front, so that later devices can "override"
- * earlier defaults
- */
- list_add(&misc->list, &misc_list);
- out:
- up(&misc_sem);
- return err;
- }
- /**
- * misc_deregister - unregister a miscellaneous device
- * @misc: device to unregister
- *
- * Unregister a miscellaneous device that was previously
- * successfully registered with misc_register(). Success
- * is indicated by a zero return, a negative errno code
- * indicates an error.
- */
- int misc_deregister(struct miscdevice * misc)
- {
- int i = misc->minor;
- if (list_empty(&misc->list))
- return -EINVAL;
- down(&misc_sem);
- list_del(&misc->list);
- class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
- if (i < DYNAMIC_MINORS && i>0) {
- misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
- }
- up(&misc_sem);
- return 0;
- }
- EXPORT_SYMBOL(misc_register);
- EXPORT_SYMBOL(misc_deregister);
- static int __init misc_init(void)
- {
- #ifdef CONFIG_PROC_FS
- struct proc_dir_entry *ent;
- ent = create_proc_entry("misc", 0, NULL);
- if (ent)
- ent->proc_fops = &misc_proc_fops;
- #endif
- misc_class = class_create(THIS_MODULE, "misc");
- if (IS_ERR(misc_class))
- return PTR_ERR(misc_class);
- if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
- printk("unable to get major %d for misc devices/n",MISC_MAJOR);
- class_destroy(misc_class);
- return -EIO;
- }
- return 0;
- }
- subsys_initcall(misc_init);
阅读(2186) | 评论(0) | 转发(0) |