1、mdev的使用方法和原理:
mdev是busybox 自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox 为基础构建嵌入式linux 的根文件系统时,使用它是最优的选择
下面介绍使用方法:
以字符设备char_dev为例,在驱动初始化的代码里调用class_create为该设备创建一个class,再为每个设备调用class_device_create创建对应的设备,这样的module被加载时,undev daemon就会自动在/dev下创建char_dev设备文件。大概方法如下:
struct class *myclass = class_create(THIS_MODULE, “char_dev”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));
以上函数均在头文件#include<linux/device.h>中定义:
1、
#define class_create(owner, name) \ ({ \ static struct lock_class_key __key; \ __class_create(owner, name, &__key); \owner 是拥有这个class的模块,name是要创建的class的名字 })
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
* @name: pointer to a string for the name of this class.
* @key: the lock_class_key for this class; used by mutex lock debugging
extern struct class * __must_check __class_create(struct module*owner, const char *name, struct lock_class_key *key);
2、
/** * class_destroy - destroys a struct class structure * @cls: pointer to the struct class that is to be destroyed * * Note, the pointer to be destroyed must have been created with a call * to class_create(). */ void class_destroy(struct class *cls)
3、
/** * device_create - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @fmt: string for the device's name * * This function can be used by char device classes. A struct device * will be created in sysfs, registered to the specified class. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)
4
/** * device_destroy - removes a device that was created with device_create() * @class: pointer to the struct class that this device was registered with * @devt: the dev_t of the device that was previously registered * * This call unregisters and cleans up a device that was created with a * call to device_create(). */ void device_destroy(struct class *class, dev_t devt)
补充:
在Linux 2.6中,针对上面的这个问题不同的版本有些修改,使用前要先查看下/.../include/linux /device.h里的函数声明,如我用的是Linux 2.6.29,里面就没有class_device_create函数,而直接使用device_create就可以了,而在之前的版本如Li nux 2.6.15,里面就要用class _device_create函数
2、实例:fir_driv_auto.c
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <linux/device.h> //for mdev MODULE_LICENSE("GPL"); static struct class *fir_driv_class; //定义一个类 static int fir_driv_open(struct inode *inode,struct file *file) { printk("first dirve open --xmkk\n"); return 0; } static int fir_driv_write(struct inode *inode ,struct file *file) { printk("first dirve write --xmkk\n"); return 0; } static struct file_operations fir_driv_fops={ .owner = THIS_MODULE, .open = fir_driv_open, .write = fir_driv_write, }; int major; static int __init fir_driv_init(void) { printk("<1>\n Hello,First drive!\n"); major=register_chrdev(0, "fir_dev", &fir_driv_fops); //新建类 fir_driv_class = class_create(THIS_MODULE, "fir_dev"); if(IS_ERR(fir_driv_class)) return PTR_ERR(fir_driv_class); //创建设备 /dev/fir_dev device_create(fir_driv_class,NULL,MKDEV(major, 0),NULL,"fir_dev"); return 0; } static void __exit fir_driv_exit(void) { printk("<1>\n Exit!\n"); //删除设备结点 device_destroy(fir_driv_class,MKDEV(major, 0)); class_destroy(fir_driv_class); unregister_chrdev(major, "fir_dev"); } module_init(fir_driv_init); module_exit(fir_driv_exit); MODULE_LICENSE("GPL");