参考资料:LDD3,精通Linux设备驱动程序
关键字: 图解杂设备驱动程序
Linux版本:3.3
混杂驱动程序是那些简单的字符驱动程序,它们拥有一些相同的特性。内核将这些共同性抽象至一个API中,这简化了这些驱动程序初始化的方式。所有的混杂设备都被分配一个主设备号10,但每个设备可选择一个单独的次设备号。
之前的字符设备的注册需要使用以下几个API:
- 通过alloc_chrdev_region()及相关函数分配主/次设备号。
- 使用device_create()创建/dev和/sys节点。
- 使用cdev_init()和cdev_add()将自身注册为字符驱动程序。
而混杂设备只需要使用一个API即可: misc_register(),内核已经帮我们做好了一切。
使用MISC_DYNAMIC_MINOR内核会自动分配一个次设备号,但主设备号是固定为10的。
简单的杂设备驱动程序实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
static int myopen(struct inode *inode, struct file *filp)
{
printk("myopen!\n");
return 0;
}
static int myrelease(struct inode *inode, struct file *filp)
{
printk("myrelease\n");
return 0;
}
static int myread(struct file *filp, const char __user *buf, size_t len, loff_t *loff)
{
printk("myread\n");
return 0;
}
static int mywrite(struct file *filp, const char __user *buf, size_t len, loff_t *loff)
{
printk("mywrite!\n");
return 0;
}
struct file_operations fops = {
.owner = THIS_MODULE,
.open = myopen,
.release = myrelease,
.read = myread,
.write = mywrite,
};
/*
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;
umode_t mode;
};
*/
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR, //动态分配次设备号
.name = "my_misc",
.fops = &fops, //将fops和设备关联
};
static int __init test_init(void)
{
int res;
printk("hello kernel!\n");
/**
* int misc_register(struct miscdevice *misc)
*/
res = misc_register(&misc);
return res;
}
static void __exit test_exit(void)
{
printk("exit kernel!\n");
misc_deregister(&misc);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HGL");
insmod test.ko后就可以在相应的目录下找到相应的文件了。
misc_register分析流程图
这里就不贴代码了.基于linux kernel3.3。