linux 混杂设备模型
在Linux系统中,存在一类字符设备,他们共享一个主设备号(10),但此设备号不同,我们称这类设备为混杂设备(miscdeivce),查看/proc/device中可以看到一个名为misc的主设备号为10.所有的混杂设备形成一个链表,对设备访问时内核根据次设备号找到对应的miscdevice设备。
Linux内核使用struct miscdeivce来描述一个混杂设备
struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};
minor是这个混杂设备的次设备号,若由系统自动配置,则可以设置为MISC_DYNANIC_MINOR,name是设备名.使用时只需填写minor次设备号,*name设备名,*fops文件操作函数集即可。
Linux内核使用misc_register函数注册一个混杂设备,使用misc_deregister移除一个混杂设备。注册成功后,linux内核为自动为该设备创建设备节点,在/dev/下会产生相应的节点。
注册函数:
int misc_register(struct miscdevice * misc)
输入参数:struct miscdevice
返回值:
表示注册成功。
负数 表示未成功。
卸载函数:
int misc_deregister(struct miscdevice *misc)
0 表示成功。
负数 表示失败。
下面是基于linux 混杂设备模型的一个简单示例:
view sourceprint?01 #include <linux/module.h>
02 #include <linux/kernel.h>
03 #include <linux/types.h>
04 #include <linux/fs.h>
05 #include <linux/init.h>
06 #include <linux/delay.h>
07 #include <asm/uaccess.h>
08 #include <asm/irq.h>
09 #include <asm/io.h>
10 #include <linux/cdev.h>
11 #include <linux/device.h>
12 #include <linux/miscdevice.h>
13 #define DEVICE_NAME "BELL-Control"
14 volatile unsigned long *gpbcon = NULL ;
15 volatile unsigned long *gpbdat = NULL ;
16 volatile unsigned long *gpbup = NULL ;
17 static int bell_drv_open(struct inode *inode, struct file *file)
18 {
19 *gpbcon &= ~(0x3<<(0*2));
20 *gpbcon |= (0x1<<(0*2)) ;
21 *gpbup = 0x0;
22 printk("first_drv_open/n");
23 return 0;
24 }
25
26 static ssize_t bell_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
27 {
28 int val;
29 copy_from_user(&val, buf, count) ;
30 if (val == 1)
31 {
32 *gpbdat &= ~(1<<0);
33 printk("first_drv_write 1111111/n");
34 }
35 else
36 {
37
38 *gpbdat |= (1<<0);
39 printk("first_drv_write 00000/n");
40 }
41 return 0;
42 }
43
44 static struct file_operations bell_drv_fops = {
45 .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
46 .open = bell_drv_open,
47 .write = bell_drv_write,
48 };
49 //注册混杂设备,每一个misc驱动会自动出现在/sys/class/misc/下
50 static struct miscdevice misc = {
51 .minor =MISC_DYNAMIC_MINOR,
52 .name = DEVICE_NAME,
53 .fops = &bell_drv_fops,
54 };
55
56 static int bell_drv_init(void)
57 {
58 int result;
59 result = misc_register(&misc);
60 printk (""DEVICE_NAME" initialized/n");
61 gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
62 gpbdat = gpbcon + 1;
63 gpbup = gpbcon + 2;
64 return 0;
65 }
66
67 static void bell_drv_exit(void)
68 {
69 misc_deregister(&misc);
70 iounmap(gpbcon);
71 }
72
73 module_init(bell_drv_init);
74 module_exit(bell_drv_exit);
75 MODULE_LICENSE("GPL");
摘自:liufazhang的博客