cdev
是内核的字符设备表示。一般思路是将cdev
与一组file_operations
相关联。这些file_operations
在设备节点上执行,通常出现在/dev
下。使用cdev_init()
将与一组file_operations
进行关联/链接。最后,在设备上调用cdev_add()
使其生效,以便用户可以访问它们。
尽管完成了上述操作,但并不意味着已为您创建了设备节点。这需要手动使用mknod
实用程序完成(如LDD3中所解释的那样)。通常情况下,驱动程序应该创建设备节点。使用device_create()
函数可实现此目的。设备节点通常与类关联。因此,我们需要首先创建一个类(使用class_create()
),然后使用该类创建设备节点。
让我通过一个示例来解释这个问题。只考虑init
函数(避免错误处理以保持清晰):
struct class *my_class;
struct cdev my_cdev[N_MINORS];
dev_t dev_num;
static int __init my_init(void)
{
int i;
dev_t curr_dev;
alloc_chrdev_region(&dev_num, 0, N_MINORS, "my_driver");
my_class = class_create(THIS_MODULE, "my_driver_class");
for (i = 0; i < N_MINORS; i++) {
cdev_init(&my_cdev[i], &fops);
curr_dev = MKDEV(MAJOR(dev_num), MINOR(dev_num) + i);
device_create(my_class, NULL, curr_dev, NULL, "my_dev%d", i);
cdev_add(&my_cdev[i], curr_dev, 1);
}
return 0;
}
现在,我逐个回答你的问题:
那么,新界面是试图改变失败的东西吗?因此推荐继续使用 device_create
吗?
这不是一个新接口。它可以说是一个扩展,通常用于创建设备节点。它还带来了创建 sysfs 属性的优点,这提供了更灵活的访问内核资源的方式。函数device_create()
返回指向struct device
的指针,在内核中具有非常强大的意义。请查看 LDD3 中关于“Linux 设备模型”的章节。
如果建议使用 cdev,那么如何创建 sysfs 条目?
cdev
和 sysfs 条目彼此独立。即使没有 cdev,您也可以创建 sysfs 条目。同样,请查看 LDD3 中关于“Linux 设备模型”的章节。您还可以查看此示例代码以创建 sysfs 条目:http://lxr.free-electrons.com/source/samples/kobject/kobject-example.c
我从来没有真正理解拥有设备类的好处,是否有必要,并且如果有,如何使用 cdev 实现它?
我希望上面的代码回答了这个问题。
通常情况下,您可能根本不会在驱动程序中使用 cdev
。 cdev
是一个非常低级别的表示。使用 cdev
构建了许多强大的设备类型框架,例如输入、tty、ALSA、IIO 等等。所有这些框架都是建立在 cdev
之上的。因此,您可能不会直接使用 cdev
。相反,您可以向这些框架注册并以更高效的方式访问设备。向这些框架注册还会为您创建设备节点和 sysfs 条目。
希望这有所帮助。