【Linux驅動】自動建立裝置節點

來源:互聯網
上載者:User

開始學習驅動的時候,是將驅動程式編譯成模組然後用mknod命令手動建立裝置節點以提供給應用程式調用。這對於剛開始調試驅動程式的時候常用的一種方法。但是,當有種需要必須在系統啟動的時候就將驅動程式就緒,來供應用程式層程式調用。這時就不能再手動的建立裝置節點了,而必須自動的建立裝置節點(不需要人為的操作)。

★註冊類

註冊類的目的是為了使mdev可以在/dev/目錄下建立裝置節點。

首先要定義一個類,利用struct class結構體。這個結構體定義在標頭檔include/linux/device.h中

struct class {const char* name;struct module* owner;struct subsystemsubsys;struct list_headchildren;struct list_headdevices;struct list_headinterfaces;struct semaphoresem;/* locks both the children and interfaces lists */struct kobject*virtual_dir;struct class_attribute* class_attrs;struct class_device_attribute* class_dev_attrs;struct device_attribute* dev_attrs;int(*uevent)(struct class_device *dev, char **envp,   int num_envp, char *buffer, int buffer_size);int(*dev_uevent)(struct device *dev, char **envp, int num_envp,char *buffer, int buffer_size);void(*release)(struct class_device *dev);void(*class_release)(struct class *class);void(*dev_release)(struct device *dev);int(*suspend)(struct device *, pm_message_t state);int(*resume)(struct device *);}


然後使用

完成對類的註冊。其中第一個參數一般為:THIS_MODULE。第二個參數為:裝置節點的名稱

舉個例子:

★建立裝置節點

建立裝置節點的函數:

<pre name="code" class="cpp">struct device *device_create(struct class *class, struct device *parent,dev_t devt, const char *fmt, ...){va_list args;struct device *dev = NULL;int retval = -ENODEV;if (class == NULL || IS_ERR(class))goto error;dev = kzalloc(sizeof(*dev), GFP_KERNEL);if (!dev) {retval = -ENOMEM;goto error;}dev->devt = devt;dev->class = class;dev->parent = parent;dev->release = device_create_release;va_start(args, fmt);vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);va_end(args);retval = device_register(dev);if (retval)goto error;return dev;error:kfree(dev);return ERR_PTR(retval);}


該函數的四個參數從左至右以此為:建立裝置節點所屬的類、該裝置的父節點(若果沒有就指定為NULL)、裝置號、裝置名稱、次裝置號。

★銷毀類和裝置節點

注意不要忘記了還要銷毀類和銷毀裝置節點。

銷毀類:參數為用struct class結構體定義的變數

void class_destroy(struct class *cls){if ((cls == NULL) || (IS_ERR(cls)))return;class_unregister(cls);}
銷毀裝置節點:

void device_destroy(struct class *class, dev_t devt){struct device *dev = NULL;struct device *dev_tmp;down(&class->sem);list_for_each_entry(dev_tmp, &class->devices, node) {if (dev_tmp->devt == devt) {dev = dev_tmp;break;}}up(&class->sem);if (dev)device_unregister(dev);}

★例子(自己寫的延時驅動)

#include <linux/miscdevice.h>    #include <linux/delay.h>    #include <asm/irq.h>#include <linux/kernel.h>    #include <linux/module.h>#include <linux/delay.h>#include <linux/unistd.h>#include <linux/string.h>#include <linux/fcntl.h>#include <asm/uaccess.h>#include <linux/kdev_t.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/version.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/interrupt.h>#include <linux/sched.h>#include <linux/device.h> #define NAME"ralink_drive_delay"#define RALINK_GPIO_DEVNAME "my_delay" #define delay_us 0     //most least is 10 US#define delay_ms 1     //Msint delay_MAJOR = 109;MODULE_LICENSE("Dual BSD/GPL");static long Ralink_delay_ioctl(struct inode * inode, struct file * file, unsigned int cmd,unsigned long arg){        switch(cmd)    {            case delay_us:                 udelay(10 * arg);                return 0;            case delay_ms:                udelay(1000);                return 0;            default:                return -1;    }}static struct file_operations My_delay_fops = {    .owner = THIS_MODULE,    .ioctl = Ralink_delay_ioctl,};static struct class *delay_class;static int __init my_delay_init(void){    int ret = 0;    ret = register_chrdev(delay_MAJOR, RALINK_GPIO_DEVNAME,&My_delay_fops);    if(ret < 0)    {        printk("unable to register character device\n");        return ret;    }    if (delay_MAJOR == 0)     {    delay_MAJOR = ret;    printk(KERN_DEBUG NAME ": got dynamic major %d\n", ret);    }         //註冊一個類,使mdev可以在"/dev/目錄下建立裝置節點"    delay_class = class_create(THIS_MODULE, RALINK_GPIO_DEVNAME);    if(IS_ERR(delay_class))    {        printk("failed in My_led class.\n");        return -1;                           }     device_create(delay_class, NULL, MKDEV(delay_MAJOR, 0),RALINK_GPIO_DEVNAME 0);//    //第一個參數是所要建立的裝置所從屬的類    //第二個參數是這個裝置的父節點,沒有指定就是NULL     //第三個參數是裝置號    //第四個參數是裝置名稱    //第五個參數是從裝置號     printk("my_delay driver initialized\n");    return 0;}void __exit my_delay_exit(void){    unregister_chrdev(delay_MAJOR,RALINK_GPIO_DEVNAME);    device_destroy(delay_class,MKDEV(delay_MAJOR,0));//登出裝置節點     class_destroy(delay_class);//銷毀類     printk("my_delay driver exited\n");    }module_init(my_delay_init);module_exit(my_delay_exit);







聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.