04_Linux驱动_06_GPIO子系统总结

GPIO子系统有新旧两种:总结的是新版的GPIO子系统。

新版GPIO子系统是基于描述符来实现的。

一,描述符(gpio_desc结构体)

cpp 复制代码
/* 
 * 内核源码目录下的"drivers/gpio/gpiolib.h"文件中
 * 作用:GPIOX的描述符,用于操作API
 */
struct gpio_desc{

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

    unsigned long flags; //标志位,用于表示不同的属性   
    /*标志位符号对应的位号*/
    #defineFLAG_REQUESTED0   //GPIO已请求
    #defineFLAG_IS_OUT1      //GPIO用作输出
    #defineFLAG_EXPORT2      //受sysfs_lock保护的导出标志
    #defineFLAG_SYSFS3       //通过/sys/class/gpio/control导出的标志
    #defineFLAG_ACTIVE_LOW6     //GPIO值为低电平时激活
    #defineFLAG_OPEN_DRAIN7     //GPIO为开漏类型
    #defineFLAG_OPEN_SOURCE8    //GPIO为开源类型
    #defineFLAG_USED_AS_IRQ9    //GPIO连接到中断请求(IRQ)
    #defineFLAG_IS_HOGGED11     //GPIO被独占占用
    #defineFLAG_TRANSITORY12    //GPIO在休眠或复位时可能失去值

    /*连接标签*/
    const char*label;      //GPIO的名称
    const char*name;       //GPIO的名称

};

--->>>
/* 
 * 内核源码目录下的"drivers/gpio/gpiolib.h"文件中
 * 作用:描述GPIO设备
 */
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

};

--->>>
/* 
 * 内核源码目录下的"include/linux/gpio/driver.h"文件中
 * 作用:描述GPIO芯片的属性和操作函数
 */
struct gpio_chip {
    
    ..........
};

二,相关API函数

2.1 获取GPIO描述符

cpp 复制代码
struct gpio_desc *gpiod_get(struct device *dev,const char *con_id,
                            enumgpiod_flags flags);

struct gpio_desc *gpiod_get_index(struct device *dev, const char *con_id,
                                  unsigned int idx, enum gpiod_flags flags);

struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id,
                                     enum gpiod_flags flags);

struct gpio_desc *gpiod_get_index_optional(struct device *dev,
                const char *con_id,unsigned int index,enum gpiod_flags flags);

1,dev:指向设备结构体的指针,表示与GPIO相关联的设备

2,con_id:连接标识符(connection identifier),用于标识所需的GPIO连接。通常由设备树(Devic eTree)或其他设备描述信息定义

3,flags:GPIO描述符的选项标志,用于指定GPIO的属性和操作模式: enum gpiod_flags

4,index:表示GPIO的索引值,当设备树的GPIO属性值包含多个GPIO引脚描述时,使用 index 来表示每个GPIO引脚的唯一标识

5,带optional后缀的函数与不带optional后缀的函数在功能上是相同

2.2 释放GPIO描述符

cpp 复制代码
void gpiod_put(struct gpio_desc *desc);

2.3 GPIO操作函数

cpp 复制代码
struct gpio_desc *mygpio1;    // GPIO描述符指针
int dir,value,irq;            // 方向 值 中断号

//将GPIO设置为输出模式并设置初始值为低电平
gpiod_direction_output(mygpio1,0); 

//将GPIO设置为输入模式
int gpiod_direction_input(struct gpio_desc *desc);

//设置GPIO为高电平
gpiod_set_value(mygpio1,1); 

//获取GPIO的方向
dir = gpiod_get_direction(mygpio1); 

//获取GPIO的值
value = gpiod_get_value(mygpio1); 

//将GPIO转换为中断号
irq = gpiod_to_irq(mygpio1);

三,三级节点操作函数

四,动态切换引脚复用功能

设备树:pinctrl-names = "mygpio_func1", "mygpio_func2";

4.1GPIO子系统与pinctrl子系统相结合

设备树:pinctrl-names = "myled1";

猜测:如果 pinctrl-names != "default"; 就要调用函数来配设。

4.2 切换方式

设备树:

cpp 复制代码
my_gpio:gpio1_a0 {
    compatible = "mygpio";
    my-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
    pinctrl-names = "mygpio_func1", "mygpio_func2";
    pinctrl-0 = <&mygpio_ctrl>;
    pinctrl-1 = <&i2c3_sda>;
};

略:

相关推荐
chuanauc5 分钟前
记录一次在 centos 虚拟机 中 安装 Java环境
java·linux·centos
企鹅侠客30 分钟前
Bash与Zsh与Fish:在Linux中你应该使用哪个Shell
linux·开发语言·bash·zsh·fish
脑袋大大的1 小时前
钉钉企业应用开发技巧:在单聊会话中实现互动卡片功能
服务器·microsoft·钉钉·企业应用开发
海星船长丶2 小时前
基于docker进行渗透测试环境的快速搭建(在ubantu中docker设置代理)
运维·docker·容器
qinyia2 小时前
利用Wisdom SSH高效搭建CI/CD工作流
运维·ci/cd·ssh
是阿建吖!2 小时前
【Linux | 网络】socket编程 - 使用TCP实现服务端向客户端提供简单的服务
linux·网络·tcp/ip
渡我白衣2 小时前
Linux操作系统之进程间通信:管道概念
linux
Amelio_Ming2 小时前
C++开源项目—2048.cpp
linux·开发语言·c++
科智咨询3 小时前
双轮驱动:政策激励与外部制约下的国产服务器市场演进
运维·服务器·gpu算力
行而不知3 小时前
家庭网络中的服务器怎么对外提供服务?
运维·服务器·内网穿透·ddns