基于UDEV动态设备加载

    在linux2.4和linux2.6早期版本中,在驱动开发中,多使用mknod命令手动创建设备节点,但当动态申请设备号时必须通过命令查出设备号,再添加。或者使用DEVFS文件系统函数添加设备节点。DEVFS在现在linux内核中已取消,取而代之的是UDEV,UDEV是处于用户态的程序。它根据内核发出的EVENTS,动态创建事件。内核是通过device_create发出event,我得linux版本是linux2.6.37所以要动态创建设备节点,必须在系统中移植UDEV(很简单,这里就不说了)。

   下面我们看看在驱动中动态添加框架:

1.创建类:

   创建类在base/class.c中实现,在linux2.6.37中clase_create是一个宏在device.h中定义

#define class_create(owner, name)  \
({      \
 static struct lock_class_key __key; \
 __class_create(owner, name, &__key); \
})

struct class *__class_create(struct module *owner, const char *name,
        struct lock_class_key *key)
{
 struct class *cls;
 int retval;

 cls = kzalloc(sizeof(*cls), GFP_KERNEL);
 if (!cls) {
  retval = -ENOMEM;
  goto error;
 }

 cls->name = name;
 cls->owner = owner;
 cls->class_release = class_create_release;

 retval = __class_register(cls, key); //注册类
 if (retval)
  goto error;

 return cls;

error:
 kfree(cls);
 return ERR_PTR(retval);
}

a.在驱动程序中首先定义全局类变量:static struct  class *my_class;

b.在完成字符设备添加cdev_add完成后调用class_create创建类(其实位置无所谓,但是如果设备没有创建成功,创建没有意义): my_class = class_create(THIS_MODULE, "m24256");

c.在驱动卸载时销毁类

    class_destroy(my_class);

2.动态创建设备节点

  调用class_create给UDEV发送event,UDEV接收到后自动在/dev下创建设备节点

  device_create函数在device.h导出。在core.c中实现

struct device *device_create(struct class *class, struct device *parent,
        dev_t devt, void *drvdata, const char *fmt, ...)
{
 va_list vargs;
 struct device *dev;

 va_start(vargs, fmt);
 dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
 va_end(vargs);
 return dev;
}
EXPORT_SYMBOL_GPL(device_create);

 

 device_create(my_class, NULL,devno,NULL, "m24256");

在驱动卸载时销毁:

void device_destroy(struct class *class, dev_t devt)
{
 struct device *dev;

 dev = class_find_device(class, NULL, &devt, __match_devt);
 if (dev) {
  put_device(dev);
  device_unregister(dev);
 }
}
EXPORT_SYMBOL_GPL(device_destroy);

device_destroy(my_class, data->dev.dev);

 

你可能感兴趣的:(linux,struct,Module,null,Class,linux内核)