迅为RK3568开发板驱动指南GPIO子系统GPIO子系统API函数的引入

大怪科学 20250529

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE图形处理器。RK3568支持4K解码和1080P编码,支持SATA/PCIE/USB3.0外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568支持安卓11和linux系统,主要面向物联网网关、NVR存储、工控平板、工业检测、工控盒、卡拉OK、云终端、车载中控等行业。

​

迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板

第131章GPIO子系统API函数的引入

事实上,在前面中断课程中,已经简单接触到了GPIO子系统中的API函数,其中用来获取gpio中断编号的gpio_to_irq函数就属于GPIO子系统中的API函数,在本章节中将对GPIO子系统进行简单的介绍。

在目前的Linux内核主线中,GPIO(通用输入/输出)子系统存在两个版本,这里将两个版本区分为新版本和旧版本。新版本GPIO子系统接口是基于描述符(descriptor-based)来实现的,而旧版本的GPIO子系统接口是基于整数(integer-based)来实现的,在Linux内核中为了保持向下的兼容性,旧版本的接口在最新的内核版本中仍然得到支持,而随着时间的推移,新版本的GPIO子系统接口会越来越完善,最终完全取代旧版本,所以在本课程中主要讲解新版本的GPIO子系统接口。

新的GPIO子系统接口需要与与设备树(Device Tree)结合使用。使用设备树和新的GPIO接口可以更加灵活地配置和管理系统中的GPIO资源,提供了更好的可扩展性和可移植性。所以如果没有设备树,就无法使用新的GPIO接口。

那要如何对新旧GPIO子系统接口进行区分呢,一个明显的区别是新的GPIO子系统接口使用了以"gpiod_"作为前缀的函数命名约定,而旧的GPIO子系统接口使用了以"gpio_"作为前缀的函数命名约定。

一些区分新旧 GPIO子系统接口的示例如下所示:

新的 GPIO子系统接口示例如下所示:

gpiod_set_value()

gpiod_direction_input()

gpiod_direction_output()

gpiod_get_value()

gpiod_request()

AI写代码

cpp

旧的 GPIO子系统接口示例:

gpio_set_value()

gpio_direction_input()

gpio_direction_output()

gpio_get_value()

gpio_request()

AI写代码

cpp

上面也提到了新的 GPIO子系统接口是基于描述符(descriptor-based)来实现的,由struct gpio_desc结构体来表示,该结构体定义在内核源码的“drivers/gpio/gpiolib.h”目录下。具体内容如下所示:

struct gpio_desc {

struct gpio_device gdev; // GPIO设备结构体

unsigned long flags; //标志位,用于表示不同的属性

/*标志位符号对应的位号*/

#define FLAG_REQUESTED 0 // GPIO已请求

#define FLAG_IS_OUT 1 // GPIO用作输出

#define FLAG_EXPORT 2 //受sysfs_lock保护的导出标志

#define FLAG_SYSFS 3 //通过/sys/class/gpio/control导出的标志

#define FLAG_ACTIVE_LOW 6 // GPIO值为低电平时激活

#define FLAG_OPEN_DRAIN 7 // GPIO为开漏类型

#define FLAG_OPEN_SOURCE 8 // GPIO为开源类型

#define FLAG_USED_AS_IRQ 9 // GPIO连接到中断请求(IRQ)

#define FLAG_IS_HOGGED 11 // GPIO被独占占用

#define FLAG_TRANSITORY 12 // GPIO在休眠或复位时可能失去值

/*连接标签*/

const char *label; // GPIO的名称

const char *name; // GPIO的名称

};

AI写代码

cpp

(1)struct gpio_device gdev是一个struct gpio_device类型的字段,用于表示GPIO设备的相关信息。struct gpio_device结构体通常包含设备的底层硬件控制器等信息。

(2)unsigned long flags:用于表示GPIO的标志位,以表示不同的属性。通过使用位操作,每个标志位可以单独设置或清除。

(3)第5-14行用于表示不同标志位的符号常量,与flags字段中的位号相对应。例如,在flags字段中的第0位表示FLAG_REQUESTED,第1位表示FLAG_IS_OUT,以此类推

(4)const char *label:这是一个指向字符串的指针,表示GPIO的标签或名称。

(5)const char *name:这是一个指向字符串的指针,表示GPIO的名称。

上面需要重点关注的是然后struct gpio_device结构体,该结构体同样定义在内核源码的“drivers/gpio/gpiolib.h”目录下,具体内容如下所示:

struct gpio_device {

int id; // GPIO设备ID

struct device *dev; //对应的设备结构体指针

struct cdev chrdev; //字符设备结构体

struct device *mockdev; //模拟设备结构体指针

struct module *owner; //拥有该GPIO设备的内核模块指针

struct gpio_chip *chip; //对应的GPIO芯片结构体指针

struct gpio_desc *descs; // GPIO描述符数组指针

int base; // GPIO编号的起始值

u16 ngpio; // GPIO的数量

const char *label; // GPIO设备的标签

void *data; //与GPIO设备相关的数据指针

struct list_head list; //用于将GPIO设备结构体连接到链表中

#ifdef CONFIG_PINCTRL

/*

*如果启用了CONFIG_PINCTRL选项,GPIO控制器可以选择描述它们在SoC中服务的实际引脚范围。

*此信息将由pinctrl子系统用于配置相应的GPIO引脚。

*/

struct list_head pin_ranges; //描述GPIO控制器引脚范围的链表

#endif

};

AI写代码

cpp

该结构体是用来描述GPIO设备的数据结构,关于该结构体的参数介绍如下所示:

(1)int id:整型字段,表示GPIO设备的ID。每个GPIO设备可以有一个唯一的ID。

(2)struct device *dev:指向struct device的指针,表示与GPIO设备相关联的设备结构体。

(3)struct cdev chrdev:字符设备结构体,用于实现GPIO设备的字符设备接口。

(4)struct device *mockdev:指向struct device的指针,用于表示GPIO设备的模拟设备结构体。

(5)struct module *owner:指向拥有该GPIO设备的内核模块的指针。

(6)struct gpio_chip *chip:指向struct gpio_chip的指针,表示与GPIO设备关联的GPIO芯片(GPIO控制器)结构体。

(7)struct gpio_desc *descs:指向struct gpio_desc数组的指针,表示与GPIO设备关联的GPIO描述符。每个GPIO描述符用于描述GPIO的属性和状态。

(8)int base:表示GPIO编号的起始值。

(9)u16 ngpio: 16位无符号整型字段,表示GPIO的数量。

(10)const char *label:指向字符串的指针,表示GPIO设备的标签或名称。

(11)void *data:指向与GPIO设备相关的数据的指针,用于存储和访问与GPIO设备相关的自定义数据。

(12)struct list_head list:将GPIO设备结构体连接到链表中的字段,用于管理多个GPIO设备的列表。

(13)struct list_head pin_ranges (仅在启用CONFIG_PINCTRL选项时存在):用于描述GPIO控制器引脚范围的链表。如果配置了GPIO控制器的引脚范围,该链表将包含描述每个范围的元素。

在上面一系列的参数中,要重点关注的是struct gpio_chip *chip这一结构体,表示与GPIO设备关联的GPIO芯片(GPIO控制器)结构体,该结构体定义在内核源码目录下的“include/linux/gpio/driver.h”文件中,具体内容如下所示

struct gpio_chip {

const char *label; // GPIO芯片标签

struct gpio_device gpiodev; // GPIO设备

struct device *parent; //父设备指针

struct module *owner; //拥有者模块指针

int (*request)(struct gpio_chip *chip, unsigned offset);//请求GPIO

void (*free)(struct gpio_chip *chip, unsigned offset); //释放GPIO

int (*get_direction)(struct gpio_chip *chip, unsigned offset); //获取GPIO方向

int (*direction_input)(struct gpio_chip *chip, unsigned offset); //设置GPIO为输入

int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value); //设置GPIO为输出

int (*get)(struct gpio_chip chip, unsigned offset); //获取GPIO值

int (*get_multiple)(struct gpio_chip chip, unsigned long *mask, unsigned long *bits); //获取多个GPIO的值

void (*set)(struct gpio_chip chip, unsigned offset, int value); //设置GPIO值

void (*set_multiple)(struct gpio_chip chip, unsigned long mask, unsigned long *bits); //设置多个GPIO的值

int (*set_config)(struct gpio_chip *chip, unsigned offset, unsigned long config); //设置GPIO配置

int (*to_irq)(struct gpio_chip chip, unsigned offset); //将GPIO转换为中断

void (*dbg_show)(struct seq_file *s, struct gpio_chip chip); //在调试信息中显示GPIO

int base; // GPIO编号的基准值

u16 ngpio; // GPIO的数量

const char *const *names; // GPIO的名称数组

..........

};

AI写代码

cpp

struct gpio_chip *chip这一结构体用于描述GPIO芯片的属性和操作函数,可以通过函数指针调用相应的函数来请求、释放、设置、获取GPIO的状态和数值等操作,从而实现对GPIO的控制和管理,需要注意的是这个结构体中的一系列函数都不需要我们来填充,这些工作都是由芯片原厂工程师来完成的,我们只需要学会新gpio子系统相应API函数的使用即可。

在接下来的章节中将对常用的新gpio子系统API函数进行讲解。

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/BeiJingXunWei/article/details/135569658

查看全文

点赞

大怪科学

作者最近更新

  • 凯米斯MS-300井下水质监测预警站:深井之下的水质守护者
    大怪科学
    14小时前
  • 潜水腕表的新宠—MS5839小型温压复合传感器
    大怪科学
    15小时前
  • ADI最新上线传感器技术电子书
    大怪科学
    13小时前

期刊订阅

相关推荐

  • 汉威科技:公司传感器已在国际具有一定的知名度和影响力,将力争在传感器行业领域产出更多的创新产品

    传感器专家网 2022-05-26

  • 从源头控制污染:甲烷传感器在油气回收中的应用

    四方光电 2024-09-12

  • 福州大学:可控超大孔结构和高延展性的明胶水凝胶传感器!

    传感器专家网 2022-05-24

  • 国产替代正当其时,四方光电引领柴油发动机氮氧传感器技术突破

    四方光电Cubic 03-14 16:00

评论0条评论

×
私信给大怪科学

点击打开传感搜小程序 - 速览海量产品,精准对接供需

  • 收藏

  • 评论

  • 点赞

  • 分享

收藏文章×

已选择0个收藏夹

新建收藏夹
完成
创建收藏夹 ×
取消 保存

1.点击右上角

2.分享到“朋友圈”或“发送给好友”

×

微信扫一扫,分享到朋友圈

推荐使用浏览器内置分享功能

×

关注微信订阅号

关注微信订阅号,了解更多传感器动态

  • #{faceHtml}

    #{user_name}#{created_at}

    #{content}

    展开

    #{like_count} #{dislike_count} 查看评论 回复

    共#{comment_count}条评论

    加载更多

  • #{ahtml}#{created_at}

    #{content}

    展开

    #{like_count} #{dislike_count} #{reback} 回复

  • #{ahtml}#{created_at}

    #{content}

    展开

    #{like_count} #{dislike_count} 回复

  • 关闭
      广告