zoukankan      html  css  js  c++  java
  • 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");
  • 相关阅读:
    Cocos2d-x之绘制线条
    Cocos2d-x之绘制填充不规则多边形
    unittest
    检查代码错误和代码风格问题
    命名
    二进制数据
    python 后台运行
    分页
    编码
    格式化
  • 原文地址:https://www.cnblogs.com/xmkk/p/3416501.html
Copyright © 2011-2022 走看看