嵌入式Linux函数

本文介绍了Linux字符设备驱动编程中的关键函数,如动态分配设备号(alloc_chrdev_region),释放设备号(unregister_chrdev_region),初始化字符设备(cdev_init),以及GPIO操作(gpio_set_value,gpio_request,gpio_direction_output,gpio_free)。这些函数在驱动开发中起到基础性作用。
摘要由CSDN通过智能技术生成

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 编号。

  • 44
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值