【Linux驱动】自动创建设备节点

更新日期:2021-10-15

来源:纯净之家


系统大全为您提供

开始学习驱动的时候,是将驱动程序编译成模块然后用mknod命令手动建立设备节点以提供给应用程序调用。这对于刚开始调试驱动程序的时候常用的一种方法。但是,当有种需要必须在系统启动的时候就将驱动程序就绪,来供应用层程序调用。这时就不能再手动的建立设备节点了,而必须自动的创建设备节点(不需要人为的操作)。
★注册类
注册类的目的是为了使mdev可以在/dev/目录下建立设备节点。
首先要定义一个类,利用struct class结构体。这个结构体定义在头文件include

nux/device.h中
struct class {
const char * name;
struct module * owner;

struct subsystem subsys;
struct list_head children;
struct list_head devices;
struct list_head interfaces;
struct semaphore sem; /* 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 *);
然后使用

【Linux驱动】自动创建设备节点

 
 完成对类的注册。其中第一个参数一般为: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

ersion.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 ");        return ret;    }    if (delay_MAJOR == 0)     {     delay_MAJOR = ret;     printk(KERN_DEBUG NAME ": got dynamic major %d ", ret);    }         //注册一个类,使mdev可以在"/dev/目录下建立设备节点"    delay_class = class_create(THIS_MODULE, RALINK_GPIO_DEVNAME);    if(IS_ERR(delay_class))    {        printk("failed in My_led class. ");        return -1;                           }     device_create(delay_class, NULL, MKDEV(delay_MAJOR, 0),RALINK_GPIO_DEVNAME 0);//    //第一个参数是所要创建的设备所从属的类    //第二个参数是这个设备的父节点,没有指定就是NULL     //第三个参数是设备号    //第四个参数是设备名称    //第五个参数是从设备号     printk("my_delay driver initialized ");    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 ");    }module_init(my_delay_init);module_exit(my_delay_exit); 
 
 
  
  以上就是系统大全给大家介绍的如何使的方法都有一定的了解了吧,好了,如果大家还想了解更多的资讯,那就赶紧点击系统大全官网吧。 
 
本文来自系统大全http://www.win7cn.com/如需转载请注明!推荐:win7纯净版