linux设备驱动----利用mdev(udev)自动创建设备文件节点

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
");

    return 0;

}



static int fir_driv_write(struct inode *inode ,struct file *file)

{

    printk("first dirve write --xmkk
");

    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>
     Hello,First drive!
");

    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>
     Exit!
");

    //删除设备结点

    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");
原文地址:https://www.cnblogs.com/xmkk/p/3416501.html