gpio设置教程,gpio模式怎么设置

首页 > 经验 > 作者:YD1662022-11-06 11:58:02

gpio设置教程,gpio模式怎么设置(1)

作者 | 赵青窕

随着Linux内核代码的逐步完善,其gpio口的操作接口也在不断完善。内核中存在多种GPIO API接口,我们该如何使用这些API接口呢?我们又该如何在设备树中配置GPIO呢?

目前的内核中提供了三种版本的API接口供我们使用,分别是Pinctrl子系统对应的API接口和GPIO子系统对应的API接口(GPIO子系统提供了两种类型的API接口),在本文中我将会通过内核中GPIO架构的角度来说明这三类API接口;我们对GPIO的控制,除了合适的API接口外,还需要通过设备树对GPIO进行配置,虽然不同架构中设备树的配置方式不同,但本文中也会举例说明设备树如何配置,对应的代码中如何使用API接口;最后说明我们可以用到的调试手段。

1.内核GPIO架构

下图是内核中,GPIO架构中的核心部分框架图(暂时不考虑GPIO架构对应的sysfs和debugfs):

gpio设置教程,gpio模式怎么设置(2)

图 1:GPIO架构

从上图中的上半部分可以看出以下关键信息:

gpio_request--->gpiod_request----> gpiod_request_commit---->chip->request(系统启动时设置为gpopchip_generic_request) ---->pinctrl_gpio_request

该调用关系从GPIO子系统的API函数gpio_request最后调用了Pinctrl子系统的函数pinctrl_gpio_request,这种调用关系,也证实了Pinctrl和GPIO子系统的关系。对于其他接口,如gpio_direction_input,gpio_set_value等函数的调用,同gpio_request相似,其最后均是调用到对应的chip->direction_input,chip->set,进而调用pinctrl_gpio_direction_input,等函数,由于这类API函数比较多,在此就不展示其调用关系了;

注意:目前从我看到的代码中发现,有些厂家在实现GPIO子系统时,并非所有的功能均通过Pinctrl子系统,但gpio_request是会通过Pinctrl子系统,因为Pinctrl子系统中会标记哪些GPIO已经request了,这样后续模块采用request继续申请该资源时就会失败;不过大家放心,即使其部分功能不通过Pinctrl子系统,但其对驱动模块提供的API接口不受其影响。

2.用户驱动中控制GPIO

在编写驱动时,可以采用以下两种方式来设置:

Pinctrl控制引脚方式

下面,我以高通平台Pinctrl的方式来说明其代码和设备树的配置。

我们先来看一下设备树:

&tlmm{ client1_state1: client1_state1 { mux { pins = "gpio0"; function = "gpio"; }; config { pins = "gpio0"; bias-disable; drive-strength =<2> ; input-enable; }; }; client1_state2: client1_state2 { mux { pins = "gpio0"; function = "gpio"; }; config { pins = "gpio0"; bias-disable; drive-strength = <2>; output-high; }; }; }; &soc { client1 { pinctrl-names = "state1", "state2"; pinctrl-0 = <&client1_state1 >; pinctrl-1 = <&client1_state2>; }; }; 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.

上面是典型的设备树的配置,其中包含两个节点,分别是tlmm中的引脚配置和我们的设备client1。

tlmm中定义了两种GPIO状态,分别是作为输入功能的GPIO0和作为输出功能的GPIO0。不同平台的设备树中的配置方法不同,但均需要像上面设备树那样,配置两部分:

引脚功能配置,是作为普通的GPIO口,还是复用为其他的功能;

引脚驱动配置,包括引脚内部的上拉或者下拉,驱动能力等。

接下来,一起看下代码中如何进行操作,其操作需要按照下面的顺序:

采用GPIO子系统

&soc { client1 { qcom,gpio-client1 = <&tlmm 100 0>; //100就是GPIO号 }1.2.3.4.5.

这种方式在设备树的配置方式上比较简单,其代码操作如下:

如果需要把引脚配置为中断功能,则我们需要使用函数irq = gpio_to_irq(gpio)来获得irq号,根据irq号来进行适当的中断配置。

通过上面两种方式,我们可以发现Pinctrl的方式,其设备树复杂,但API接口简单,只需要通过函数pinctrl_select_state选择设备树中某一配置即可。GPIO子系统的方式是设备树简单,但代码复杂,设备树中只配置了GPIO号,其余的如GPIO的方向及输出信号均需要通过代码来进行设置,这正是不同API接口及其设备树的优缺点。

3.GPIO调试

不同平台的调试方式可能会存在一些差异,比如MTK的不同平台间都会有差异,在此我就介绍一种常见的需要debugfs支持的方式。

我们在编译内核时,需要配置相应的debugfs宏来打开该功能,只有配置相应宏后,我们就可以进入机器的/sys/class/gpio下对GPIO口进行操作,下面是对应的操作顺序:

4.总结

希望大家通过本文,可以了解内核中GPIO的机制并掌握其操作方法,但需要说明的是在内核之前的阶段也会进行引脚的配置,比如我们使用串口来打印bootloader阶段的日志,这种情况下串口引脚一定是在内核之前的阶段进行配置的。

作者介绍

赵青窕,51CTO社区编辑,从事多年驱动开发。研究兴趣包含安全OS和网络安全领域,发表过网络相关专利。

来源:51CTO技术栈

作者:赵青窕

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.