• 《Pinctrl和GPIO子系统的使用》


    1.参考文档

    a. 内核 DocumentationdevicetreeindingsPinctrl 目录下:
    Pinctrl-bindings.txt
    
    b. 内核 Documentationgpio 目录下:
    Pinctrl-bindings.txt
    
    c. 内核 Documentationdevicetreeindingsgpio 目录下:
    gpio.txt
    

      

    2.Pinctrl子系统概念

      linux下的pintcrl和gpio子系统就类似于ST的“BSP库”。引入“设备树”之后,使用一个外设时,对于pin引脚的初始化和管理,只需通过设备树描述即可,然后由pin子系统管理;对于gpio则由gpio子系统管理。
      因此,与CPU引脚“关联”的设备驱动,最终都会调用pincrtl和gpio子系统。二者是设备驱动的基础,这二者也是一个设备驱动。
      CPU的gpio引脚除了的方向、速度、上下拉、驱动能力等基本的电气特性外,一般会包括复用功能,即该引脚既可以作为普通gpio,还可能复位为i2c引脚、uart引脚等。如果采用直接配置寄存器的方式进行驱动开发,会非常繁琐,每更改一个功能就得重新翻阅手册配一遍寄存器,另一方面还可能存在“冲突”问题,比如该引脚已被复用为i2c在使用,但被驱动工程师忽略了,再去使用该gpio时会导致未知预期的问题。引入pintctrl子系统就可以解决诸如此类问题,结合设备树的使用,只需把pin信息在设备树描述清楚,即由pinctrl子系统介入管理。
     
      从设备树开始学习 Pintrl 会比较容易。
      主要参考文档是:内核 Documentationdevicetreeindingspinctrlpinctrl-bindings.txt。
      这会涉及 2 个对象:pin controller、client device。
      前者提供服务:可以用它来复用引脚、配置引脚。
      后者使用服务:声明自己要使用哪些引脚的哪些功能,怎么配置它们。
     
    2.1 pin controller
      在芯片手册里你找不到 pin controller,它是一个软件上的概念,你可以认为它对应IOMUX──用来复用引脚,还可以配置引脚(比如上下拉电阻等)。
      注意,pin controller 和 GPIO Controller 不是一回事,前者控制的引脚可用于 GPIO 功能、I2C 功能;后者只是把引脚配置为输出、输出等简单的功能。
     
    2.2 client device
      “客户设备”,谁的客户?Pinctrl 系统的客户,那就是使用 Pinctrl 系统的设备,使用引脚的设备。它在设备树里会被定义为一个节点,在节点里声明要用哪些引脚。
      下面这个图就可以把几个重要概念理清楚:  上图中,左边是 pincontroller 节点,右边是 client device 节点:
    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 子系统会自动根据上述信息把所用引脚配置为高电平
     
    groups 和 function:
      一个设备会用到一个或多个引脚,这些引脚就可以归为一组(group);
      这些引脚可以复用为某个功能:function。
      当然:一个设备可以用到多能引脚,比如 A1、A2 两组引脚,A1 组复用为 F1 功能,A2组复用为 F2 功能。
     
    Generic pin multiplexing node 和 Generic pin configuration node:
      在上图左边的 pin controller 节点中,有子节点或孙节点,它们是给 client device 使用的。
      可以用来描述复用信息:哪组(group)引脚复用为哪个功能(function);
      可以用来描述配置信息:哪组(group)引脚配置为哪个设置功能(setting),比如上拉、下拉等。
     
    注意:pin controller 节点的格式,没有统一的标准!!!!每家芯片都不一样
     
     
    3.GPIO系统
      pinctrl子系统主要是管理pin的电气属性和复用功能,而gpio子系统则是管理gpio的申请释放、控制输入输出、io中断等功能。gpio子系统屏蔽了gpio相关寄存器的配置过程,换而提供了常用的接口函数给驱动工程师使用,方便gpio相关的驱动开发。 

    gpio子系统功能

    • 对于驱动层,屏蔽gpio寄存器配置细节,提供统一gpio操作接口
    • 对于BSP层,统一框架,方便不同CPU接入,只需更换pinctrl子系统的驱动
    3.1 GPIO子系统常用函数
      gpio子系统对于驱动层的API位于“/kernel/include/linux/gpio.h”中。
    (1)检查gpio是否可用
    int gpio_is_valid(int number); 
    number:	gpio序号
    返回:	可用返回true,不可用返回false
    

      

    (2)申请使用一个gpio

    使用一个gpio前,必须向内核申请该gpio。
    int gpio_request(unsigned gpio, const char *label)
    gpio:	待申请gpio序号
    label:gpio命名
    返回:	成功返回0,失败返回负数
    

      

    (3)释放已申请gpio

    如果不使用该gpio,则需要释放,否则其他模块申请不到该gpio序号。
    int gpio_free(unsigned gpio)
    gpio:待释放gpio序号
    返回:成功返回0,失败返回负数

      

    (4)设置gpio输入模式

    int gpio_direction_input(unsigned gpio)
    gpio:待设置gpio序号
    返回:成功返回0,失败返回负数
    

      

    (5)设置gpio输出模式
    void gpio_set_value(unsigned gpio, int value)
    gpio:待设置gpio序号
    value:默认输出状态
    

      

    (6)读取 gpio状态

    int gpio_get_value(unsigned int gpio)
    gpio:待读取gpio序号
    返回:成功返回gpio状态(1/0),失败返回负数
    

      

    (7)设置 gpio状态

    void gpio_set_value(unsigned int gpio, int value)
    gpio:待设置gpio序号
    value:待设置值
    

      

    (8)中断号映射

    int gpio_to_irq(unsigned gpio)
    gpio:待设置gpio序号
    返回:成功返回中断号,失败返回负数
    

      

    如果使用该 GPIO 时,不会动态的切换输入输出,建议在开始时就设置好 GPIO 输出方向,后面拉高拉低时使用 gpio_set_value()接口,而不建议使用gpio_direction_output(), 因为 gpio_direction_output 接口里面有 mutex 锁,对中断上下文调用会有错误异常,且相比 gpio_set_value,gpio_direction_output 所做事情更多,浪费。 





     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    笔试面试过程中常考的简单题目
    MySQL字符串函数:字符串截取总结
    克隆到新的datatale中
    C#后台调用js代码和其他页面(弹窗)
    asp.net中如何使一个button先执行后台的Click再执行javascript的onclick?
    table按某列进行分组
    table里有两个input,选中只选中一个
    ts和js的区别
    es6-es7-es10
    ECMAScript 6(简称:ES6) 和 JavaScript 到底是什么关系?
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/12750736.html
Copyright © 2020-2023  润新知