1.alloc_chrdev_region
功能:动态分配字符设备号的函数。在 Linux 的字符设备驱动编程中,当需要为字符设备分配主设备号和次设备号时,可以使用 alloc_chrdev_region 函数动态获取设备号。
原型:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
参数说明:
dev:用于存储分配得到的设备号,由主设备号和初始次设备号组成。
baseminor:指定起始的次设备号。
count:指定需要分配的连续次设备号的数量。
name:可选参数,用于标识设备的名字,可以在/proc/devices文件中看到。
用法:
dev_t dev;//dev_t本质上是一个unsigned int类型(32位),高 12 位表示主设备号,低 20 位表示次设备号
int err = alloc_chrdev_region(&dev, 0, 1, "my_char_device");
if (err < 0)
{
printk(KERN_ERR "Failed to allocate character device region\n");
return err;
}
2.unregister_chrdev_region
功能:用于释放先前由 alloc_chrdev_region 或 register_chrdev_region 函数分配的字符设备号
原型:
void unregister_chrdev_region(dev_t from, unsigned count);
参数说明:
from:指定需要释放的设备号范围的起始值。
count:指定释放的设备号数量。
用法:
dev_t first_dev;
int count = 1;
unregister_chrdev_region(first_dev, count);
3.cdev_init
功能:用于初始化字符设备结构体 struct cdev。struct cdev 是核心字符设备结构,用于表示一个字符设备。该结构包含了字符设备驱动程序的操作函数指针、设备号等信息,并通过链表的方式与其他字符设备结构连接在一起。
struct cdev结构体原型
struct cdev
{
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
struct kobject kobj: 用于表示字符设备的内核对象,提供了与内核对象相关的属性和方法。
struct module *owner: 指向拥有这个字符设备结构体的内核模块的指针,用于跟踪模块的所有权。
const struct file_operations *ops: 指向包含字符设备操作函数的结构体指针,用于定义字符设备的文件操作。
struct list_head list: 用于将字符设备结构体连接到字符设备的链表中,以便内核可以管理多个字符设备。
dev_t dev: 用于存储字符设备的设备号,包括主设备号和次设备号。
unsigned int count: 用于跟踪字符设备的打开计数,以便内核知道有多少个进程正在使用这个字符设备。
原型:
void cdev_init(struct cdev *cdev, const struct file_operations *fops);
参数说明:
cdev:指向要初始化的 struct cdev 对象的指针。
fops:指向该字符设备所使用的文件操作函数结构体对象 struct file_operations 的指针。
用法:
#include <linux/cdev.h>
struct cdev my_cdev;
struct file_operations my_fops = {
.owner = THIS_MODULE,
// 设置其他文件操作函数
};
int init_module(void)
{
dev_t dev = MKDEV(MY_MAJOR, MY_MINOR);
cdev_init(&my_cdev, &my_fops);
// 设置其他设备相关信息
// 注册字符设备
cdev_add(&my_cdev, dev, 1);
return 0;
}
void cleanup_module(void)
{
// 移除字符设备
cdev_del(&my_cdev);
}
4. cdev_add
功能:用于向系统注册字符设备的函数。它用于将字符设备对象添加到系统中,使得用户空间程序可以访问该字符设备。
原型:
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
参数说明:
p 是指向表示要添加到系统的字符设备对象的指针。
dev 表示要添加的字符设备的设备号。
count 表示要添加的设备号的数量。
返回值:
该函数的返回值为操作执行结果的状态码。如果函数执行成功,则返回值为 0;如果出现错误,则返回一个负的错误码,表示添加字符设备失败的原因。
注意:
在调用 cdev_add() 函数之前,需要先通过 cdev_init() 函数来初始化字符设备对象,并通过 register_chrdev_region() 或 alloc_chrdev_region() 来分配设备号。之后,再调用 cdev_add() 将字符设备对象添加到系统中。
5.GPIO
5.1 gpio_set_value
功能:用于在 Linux 内核中设置 GPIO(通用输入/输出)管脚的值。
原型
int gpio_set_value(unsigned int gpio, int value);
gpio 参数表示需要设置值的 GPIO 编号,value 参数表示要设置的值,通常是 0 或 1
5.2 gpio_request
功能:用于向内核请求一个 GPIO 管脚的控制权,以便在内核中对其进行操作。
原型:
int gpio_request(unsigned int gpio, const char *label);
参数说明:
gpio 参数表示需要请求的 GPIO 编号。
label 参数表示用于标识这个 GPIO 管脚的字符串,通常用设备或驱动程序的名称作为标识符
注意:
调用这个函数后,如果请求成功,就可以在内核中控制、配置这个 GPIO 管脚了。通常在使用完 GPIO 后,需要调用 gpio_free() 函数来释放对 GPIO 的控制权。对 GPIO 进行操作需要相应的权限,因此在内核代码中使用 gpio_request() 函数时,需要特别注意权限和错误处理。
5.3 gpio_direction_output
功能:用于设置 GPIO 管脚的方向为输出的函数
原型:
int gpio_direction_output(unsigned int gpio, int value);
参数说明:
gpio 参数表示需要设置方向的 GPIO 编号。
value 参数表示初始输出的值,通常是 0 或 1。
注意:
调用这个函数后,GPIO 管脚的方向会被设置为输出,并且初始输出的值会被设置为 value 参数指定的值。使用 gpio_direction_output() 函数来设置 GPIO 管脚方向之前,需要先调用 gpio_request() 函数来请求对 GPIO 的控制权。在使用完 GPIO 后,如果不再需要控制 GPIO,需要调用 gpio_free() 函数释放对 GPIO 的控制权。
5.4 gpio_free
功能:用于释放对 GPIO 管脚的控制权,在 Linux 内核中用于释放之前使用 gpio_request() 函数请求的 GPIO 控制权。
原型
void gpio_free(unsigned int gpio);
参数说明:
gpio 参数表示需要释放的 GPIO 编号。