GPIO和Pinctrl子系统的使用

2023-05-16

目录

  • 前言
  • Pinctrl子系统
    • 1、 重要概念
      • 1.1、pin controller
      • 1.2、client device
    • 2、代码中怎样引用pinctrl
  • GPIO子系统
    • 1.1 引入
    • 1.2 在设备树中指定引脚
    • 1.3 在驱动代码中调用GPIO子系统

前言

使用直接操作寄存器的方法编写驱动,非常低效。Linux 下针对引脚有 2 个重要的子系统:GPIO、Pinctrl。

Pinctrl子系统

无论是何种芯片都有类似下图的结构:

要想让 pinA、B 用于 GPIO,需要设置 IOMUX 让它们连接到 GPIO 模块;
要想让 pinA、B 用于 I2C,需要设置 IOMUX 让它们连接到 I2C 模块。
所以 GPIO、I2C 应该是并列的关系,它们能够使用之前,需要设置 IOMUX。有时候并不仅仅是设置 IOMUX,还要配置引脚,比如上拉、下拉、开漏等等。
现在的芯片动辄几百个引脚,在使用到 GPIO 功能时,让你一个引脚一个引脚去找对应的寄存器,这要
疯掉。
所以,要把引脚的复用、配置抽出来,做成 Pinctrl 子系统,给 GPIO、I2C 等模块使用。

1、 重要概念

1.1、pin controller

在芯片手册里你找不到 pin controller,它是一个软件上的概念,你可以认为它对应 IOMUX──用来
复用引脚,还可以配置引脚(比如上下拉电阻等)。
注意,pin controller 和 GPIO Controller 不是一回事,前者控制的引脚可用于 GPIO 功能、I2C 功能;
后者只是把引脚配置为输入、输出等简单的功能。即先用 pin controller 把引脚配置为 GPIO,再用 GPIO Controler 把引脚配置为输入或输出。

1.2、client device

“客户设备”,谁的客户?Pinctrl 系统的客户,那就是使用 Pinctrl 系统的设备,使用引脚的设备。
它在设备树里会被定义为一个节点,在节点里声明要用哪些引脚。

上图中,左边是 pin controller 节点,右边是 client device 节点:
a. pin state:
对于一个“client device”来说,比如对于一个 UART 设备,它有多个“状态”:default、sleep 等,那对应的引脚也有这些状态。
怎么理解?
比如默认状态下,UART 设备是工作的,那么所用的引脚就要复用为 UART 功能。
在休眠状态下,为了省电,可以把这些引脚复用为 GPIO 功能;或者直接把它们配置输出高电平。
上图中,pinctrl-names 里定义了 2 种状态:default、sleep。
第 0 种状态用到的引脚在 pinctrl-0 中定义,它是 state_0_node_a,位于 pincontroller 节点中。
第 1 种状态用到的引脚在 pinctrl-1 中定义,它是 state_1_node_a,位于 pincontroller 节点中。
当这个设备处于 default 状态时,pinctrl 子系统会自动根据上述信息把所用引脚复用为 uart0 功能。
当这这个设备处于 sleep 状态时,pinctrl 子系统会自动根据上述信息把所用引脚配置为高电平。
b. groups 和 function:
一个设备会用到一个或多个引脚,这些引脚就可以归为一组(group);
这些引脚可以复用为某个功能:function。
当然:一个设备可以用到多组引脚,比如 A1、A2 两组引脚,A1 组复用为 F1 功能,A2 组复用为 F2 功
能。
c. Generic pin multiplexing node 和 Generic pin configuration node
在上图左边的 pin controller 节点中,有子节点或孙节点,它们是给 client device 使用的。
可以用来描述复用信息:哪组(group)引脚复用为哪个功能(function);
可以用来描述配置信息:哪组(group)引脚配置为哪个设置功能(setting),比如上拉、下拉等。

2、代码中怎样引用pinctrl

这是透明的,我们的驱动基本不用管。当设备切换状态时,对应的 pinctrl 就会被调用。
比如在 platform_device 和 platform_driver 的枚举过程中,流程如下:

当系统休眠时,也会去设置该设备 sleep 状态对应的引脚,不需要我们自己去调用代码。

GPIO子系统

1.1 引入

要操作 GPIO 引脚,先把所用引脚配置为 GPIO 功能,这通过 Pinctrl 子系统来实现。
然后就可以根据设置引脚方向(输入还是输出)、读值──获得电平状态,写值──输出高低电平。
以前我们通过寄存器来操作 GPIO 引脚,即使 LED 驱动程序,对于不同的板子它的代码也完全不同。
当 BSP 工程师实现了 GPIO 子系统后,我们就可以:
a. 在设备树里指定 GPIO 引脚
b. 在驱动代码中:
使用 GPIO 子系统的标准函数获得 GPIO、设置 GPIO 方向、读取/设置 GPIO 值。
这样的驱动代码,将是单板无关的。

1.2 在设备树中指定引脚

在几乎所有 ARM 芯片中,GPIO 都分为几组,每组中有若干个引脚。所以在使用 GPIO 子系统之前,就要先确定:它是哪组的?组里的哪一个?
在设备树中,“GPIO 组”就是一个 GPIO Controller,这通常都由芯片厂家设置好。我们要做的是找到
它名字,比如“gpio1”,然后指定要用它里面的哪个引脚,比如<&gpio1 0>。
有代码更直观,下图是一些芯片的 GPIO 控制器节点,它们一般都是厂家定义好,在 xxx.dtsi 文件中:

我们暂时只需要关心里面的这 2 个属性:
gpio-controller;
#gpio-cells = <2>;

“gpio-controller”表示这个节点是一个 GPIO Controller,它下面有很多引脚。
“#gpio-cells = <2>”表示这个控制器下每一个引脚要用 2 个 32 位的数(cell)来描述。
为什么要用 2 个数?其实使用多个 cell 来描述一个引脚,这是 GPIO Controller 自己决定的。比如可
以用其中一个 cell 来表示那是哪一个引脚,用另一个 cell 来表示它是高电平有效还是低电平有效,甚至
还可以用更多的 cell 来示其他特性。
普遍的用法是,用第 1 个 cell 来表示哪一个引脚,用第 2 个 cell 来表示有效电平:

GPIO_ACTIVE_HIGH : 高电平有效
GPIO_ACTIVE_LOW : 低电平有效

定义 GPIO Controller 是芯片厂家的事,我们怎么引用某个引脚呢?在自己的设备节点中使用属性
“[-]gpios”,示例如下

1.3 在驱动代码中调用GPIO子系统

在设备树中指定了 GPIO 引脚,在驱动代码中如何使用?
也就是 GPIO 子系统的接口函数是什么?
GPIO 子系统有两套接口:基于描述符的(descriptor-based)、老的(legacy)。前者的函数都有前缀
“gpiod_”,它使用 gpio_desc 结构体来表示一个引脚;后者的函数都有前缀“gpio_”,它使用一个整数来
表示一个引脚。
要操作一个引脚,首先要 get 引脚,然后设置方向,读值、写值。
驱动程序中要包含头文件,

#include <linux/gpio/consumer.h> // descriptor-based#include <linux/gpio.h> // legacy

常用函数:

有前缀“devm_”的含义是“设备资源管理”(Managed Device Resource),这是一种自动释放资源的机 制。它的思想是“资源是属于设备的,设备不存在时资源就可以自动释放”。 比如在 Linux 开发过程中,先申请了 GPIO,再申请内存;如果内存申请失败,那么在返回之前就需要 先释放 GPIO 资源。如果使用 devm 的相关函数,在内存申请失败时可以直接返回:设备的销毁函数会自动地释放已经申请了的 GPIO 资源。 建议使用“devm_”版本的相关函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPIO和Pinctrl子系统的使用 的相关文章

  • m3u直播源_M3U播放列表生成工具

    来源 xff1a 黑鸟博客 快速制作支持 VLC 和 Potplayer 等播放器的 XSPF DPL M3U 等播放列表格式的工具 xff0c 并且可以查重复 xff0c 自定义设置多种选项 所有的播放列表都可以使用普通的文本编辑器 xf
  • js字符串包含另一个字符串_C语言中,在一个字符串中插入另一个字符串(字符)...

    本题可以看做一个字符串拼接问题 需要一个载体数组 includevoid insert array char s1 char s2 int n 思路 1 得到主串s1和子串s22 找到插入位置 3 进行插入 void main char s
  • 华为手机一键解锁工具箱下载 | 华为手机解BL锁软件: 支持解锁bootloader,刷写recovery功能

    文章目录 1 软件介绍2 特色功能3 资源站点4 下载地址5 软件截图6 安装教程7 使用教程7 1 解锁BL 1 软件介绍 通过这款华为手机实用工具箱可以对你的华为手机系列进行刷机 解锁等操作 xff0c 网上这种华为刷机解锁工具比较少
  • python subprocess 实时输出_Python标准库初探之subprocess

    一 subprocess简介 人生苦短 xff0c 我用Python 今天给大家带来一个在Python脚本中启动进程的利器 subprocess 人们都说Python是一个胶水语言 xff0c 可以方便地在多平台上调用其他指令 xff0c
  • 进程内存中堆和栈的区别

    1 概述 在整理数据结构时 xff0c 整理过栈 队列和堆 xff0c 但是在学习进程分布的时候又碰到了 栈和堆 xff0c 初学时很容易把这几个概念给弄混 xff0c 今天有空就给整理一下 2 程序在内存中的分布 程序在内存中的分布如下图
  • C++ Mutable

    1 mutable 含义及常规使用 mutable 英文中表示 xff0c 易变的 xff0c 不定的 xff1b 性情不定的 xff0c 而在代码中表示 可变数据成员 由前面整理的 const详解 知道 xff0c 由const修饰的成员
  • 牛吃草问题

    1 概述 最近碰到一个面试题 xff0c 讲的是牛吃草的问题 xff0c 当时时间短 xff0c 脑袋出现了短路 xff0c 没有给出答案 回来特意查了一下答案 xff0c 发现了一篇比较好的文章 xff0c 现在重新抄写一份 xff0c
  • 开始记录学习中的点滴

    随着年龄的增长 xff0c 除了去了很多地方之外 xff0c 感觉个人没有特别明显的成长 xff0c 对于未来充满了更多的迷茫与困惑 对于程序员的我来说更是感觉到了自己的瓶颈 xff0c 知识储备没有增加多少 xff0c 随着时间的流逝 x
  • C++中Struct与Class的区别与比较

    概述 之前只知道在C 43 43 中类和结构体的区别只有默认的防控属性 xff08 访问控制 xff09 不同 xff0c struct是public的 xff0c 而class是private的 但经过上网查资料才发现 xff0c 除了这
  • 函数调用约定的详解

    概述 在工作的过程中 xff0c 我们总是需要调用底层函数或者使用第三方的库 xff0c 在使用的过程中我就发现了有一些函数前面总有一些 stdcall xff0c 之初我只知道那是调用约定 xff0c 但别人问我什么是调用约定 xff0c
  • #pragma的常用方法讲解

    概述 我们在写代码时 xff0c 总会遇到头文件多次包含的情况 xff0c 刚开始时我们使用宏定义进行控制 xff0c 之后发现有 pragma once这样简单的东西 xff0c 当时是很兴奋 xff0c 以为 pragma就这一种用法
  • C++数组的详细解析

    概述 数组在写程序时经常用到 xff0c 但是对于它和指针的关系 xff0c 自己经常搞混 xff0c 所有抽点时间对数组进行整理 1 数组的概念和使用 数组是用来存储相同类型的变量的顺序集合 所有的数组都是由连续的内存位置组成 最低的地址
  • 华为荣耀9升降级系统 | 华为荣耀9变砖后如何救砖 | 华为荣耀9获取BL解锁码以及如何解BL锁 | 华为荣耀9如何通过写ramdisk.img来获取root

    文章目录 1 按2 通过官方华为手机助手升降级以及修复系统和安装驱动3 使用百分之五模式刷高维禁用包355来安装指定的系统版本8 0 0 3554 故意 xff08 或意外 xff09 刷错包把手机变砖5 使用救砖模式刷高维禁用包355来安
  • C++指针详解

    概述 C C 43 43 语言之所以强大 xff0c 以及其自由性 xff0c 很大部分体现在其灵活的指针运用上 因此 xff0c 说指针是C C 43 43 语言的灵魂一点都不为过 有好的一面 xff0c 必然会有坏的一面 xff0c 指
  • C++ lambda表达式及其原理

    概述 C 43 43 11中引入了新的lamdba表达式 xff0c 使用也很简单 xff0c 我最喜欢的是不用给函数取名称 xff0c 每次给函数取名称都感觉自己读书太少 1 lambda表达式 lambda表达式可以理解为一个匿名的内联
  • GIT 修改用户名和密码

    1 概述 如果你使用GIT的SSH 方式连接远端 xff0c 并且设置了一个没有口令的秘钥 xff0c 这样就可以砸不输入用户名和密码的情况下安全地传输数据 然而 xff0c 这对 HTTP 协议来说是不可能的 每一个连接都是需要用户名和密
  • bmi055 标定_Kalibr tutorials

    Kalibr installation tutorial I was confused about installing Kalibr but there is no even one hint in README md I just pu
  • python上位机例程_python 上位机通信实例

    34 moduleinfo 34 34 card count 34 34 count phone 34 1 34 count 34 1 34 search count 34 34 count phone 34 6 34 count 34 6
  • linux post请求_Linux C++网络编程

    img 前言 要想找一份Linux c 43 43 方面的好工作 xff0c 在面试过程中游刃有余 xff0c 那么这篇文章就是为你定制的 因为作为一个校招的学生 xff0c 我在学习和面试过程中的经历总这个体系的文章 xff0c 希望可以
  • 200826-C语言打印文件中的文本内容

    1 Description 在桌面上创建一个txt文件 xff0c 输入一些文本内容 xff0c 我们的任务是把文本内容打印出来 在编程之前 xff0c 关于一些函数的定义我们需要了解下 fopen fopen的函数原型为 xff1a FI

随机推荐