Linux驱动 | cdev_init、cdev_alloc的区别

原创
ithorizon 5个月前 (10-12) 阅读数 28 #Linux

Linux驱动开发:cdev_init与cdev_alloc的区别

在Linux内核中,字符设备(char device)是一种常见的设备类型,它允许用户空间的应用程序通过标准文件操作与硬件设备进行交互。在驱动程序开发中,`cdev_init`和`cdev_alloc`是两个用于初始化字符设备结构体`struct cdev`的函数。这两个函数在功能和使用上有所区别,以下是它们之间的详细比较。

### 1. cdev_init

`cdev_init`函数用于初始化一个已经分配的`cdev`结构体。这个函数接收三个参数:一个指向`cdev`结构体的指针、一个指向设备号的指针和一个指向`struct module`结构体的指针。

c

int cdev_init(struct cdev *cdev, dev_t dev, struct module *owner);

- `cdev`: 指向要初始化的`cdev`结构体的指针。

- `dev`: 指向设备号的指针,用于设置`cdev`结构体中的`dev`成员。

- `owner`: 指向`struct module`结构体的指针,描述拥有该字符设备的模块。

`cdev_init`函数将`cdev`结构体中的成员初始化为默认值,并设置`dev`成员的值。如果`cdev`结构体已经初始化,则`cdev_init`会返回失误。

### 2. cdev_alloc

`cdev_alloc`函数用于动态分配一个`cdev`结构体,并初始化它。这个函数接收两个参数:一个指向`struct module`结构体的指针和一个指向设备号的指针。

c

struct cdev *cdev_alloc(struct module *owner, dev_t dev);

- `owner`: 指向`struct module`结构体的指针,描述拥有该字符设备的模块。

- `dev`: 指向设备号的指针,用于设置新分配的`cdev`结构体中的`dev`成员。

`cdev_alloc`函数会动态分配一个`cdev`结构体,并调用`cdev_init`来初始化它。如果分配未果,则返回`NULL`。

### 3. 区别

- **分配方案**:`cdev_init`需要一个已经分配的`cdev`结构体,而`cdev_alloc`会自动分配一个`cdev`结构体。

- **初始化时机**:`cdev_init`在`cdev`结构体已经分配后调用,而`cdev_alloc`在`cdev`结构体分配时调用。

- **返回值**:`cdev_init`如果`cdev`结构体已经初始化,则返回失误;而`cdev_alloc`如果分配未果,则返回`NULL`。

### 4. 使用场景

- **cdev_init**:适用于在驱动程序中,当`cdev`结构体已经通过其他方案(如`kmalloc`)分配后,需要对其进行初始化的情况。

- **cdev_alloc**:适用于在驱动程序中,当需要动态分配并初始化一个`cdev`结构体时。

### 5. 示例代码

以下是一个单纯的示例,展示了怎样使用`cdev_init`和`cdev_alloc`:

c

#include

#include

static struct cdev my_cdev;

static dev_t my_dev = MKDEV(0, 1);

static struct module *my_owner = THIS_MODULE;

static int __init my_cdev_init(void) {

if (cdev_init(&my_cdev, my_dev, my_owner)) {

printk(KERN_ERR "Failed to initialize cdev. ");

return -EFAULT;

}

cdev_add(&my_cdev, my_dev, 1);

return 0;

}

static void __exit my_cdev_exit(void) {

cdev_del(&my_cdev);

}

module_init(my_cdev_init);

module_exit(my_cdev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Your Name");

MODULE_DESCRIPTION("Example cdev initialization");

在这个示例中,我们使用`cdev_init`来初始化一个已经通过`kmalloc`分配的`cdev`结构体。

### 6. 总结

`cdev_init`和`cdev_alloc`是Linux内核中用于初始化字符设备结构体的两个函数。它们在功能和使用上有所不同,开发者应采取具体需求选择合适的函数。本文对这两个函数进行了详细的比较和说明,愿望对Linux驱动开发有所帮助。

本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: Linux


热门