linux传统上使用静态设备创建方法,因此大量设备节点在/dev下创建(有时上千个),而不管相应的硬件设备是否真正存在。
采用udev的方法,只有被内核监测到的设备,才会去为它们创建设备节点。
当插入新设备——加入驱动模块——在sysfs上注册新的数据后,udev会创建新的设备节点。
linux系统中/sys/devices/virtual/input/xxx
路径下,dev文件和uevent文件会存储驱动的设备号以及设备的名称。
/* This is a #define to keep the compiler from merging different
* instances of the __key variable */
#define class_create(owner, name) \
({ \
static struct lock_class_key __key; \
__class_create(owner, name, &__key); \
})
参数:
返回值
定义一个struct class的指针变量cls接受返回值,然后通过IS_ERR(cls)
判断是否失败;
如果成功这个宏返回0,失败返回非0值;可以通过PTR_ERR(cls)
来获得失败返回的错误码。
/**
* 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)
{
if ((cls == NULL) || (IS_ERR(cls)))
return;
class_unregister(cls);
}
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;
}
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);
}
}
#include
#include
#include
#include
#include
static int major = 230;
static int minor = 0;
static dev_t devno;
static struct class *cls = NULL;
static struct device *class_dev = NULL;
static int hello_open(struct inode *inode, struct file *file)
{
printk("hello_open \n");
return 0;
}
static int hello_release(struct inode *inode, struct file *file)
{
printk("hello_release \n");
return 0;
}
static struct file_operations fops = {
.open = hello_open,
.release = hello_release,
};
static int hello_init(void)
{
int ret;
printk("hello_init() \n");
ret = register_chrdev(major, "hello_test", &fops);
if(ret < 0)
{
printk("register_chrdev() file\n");
return ret;
}
cls = class_create(THIS_MODULE,"hello_cls");
if (IS_ERR(cls )) {
ret = PTR_ERR(cls );
goto out_err_0;
}
devno = MKDEV(major, minor);
class_dev = device_create(cls, NULL, devno, NULL,"hello_dev");
if (IS_ERR(class_dev)) {
printk("device_create failed\n");
ret = PTR_ERR(class_dev);
goto out_err_1;
}
return 0;
out_err_1:
class_destroy(cls);
out_err_0:
unregister_chrdev(major, "hello_test");
return ret;
}
static void hello_exit(void)
{
printk("hello_exit() \n");
device_destroy(cls,devno);
class_destroy(cls);
unregister_chrdev(major, "hello_test");
return ;
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);