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

    return ;

}

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

{

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

    return ;

}

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(, "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 ;
} 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");
上一篇:Linux内核设计与实现 总结笔记(第十一章)定时器和时间管理


下一篇:javascript中break与continue,及return的区别