一.gpio查看命令
//查看引脚状态1
cat /sys/kernel/debug/gpio
//查看gpio引脚的复用情况1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18cat /sys/kernel/debug/pinctrl/pinctrl/pinmux-pins
Pinmux settings per pin
Format: pin (name): mux_owner gpio_owner hog?
pin 0 (gpio0-0): wireless-wlan (GPIO UNCLAIMED) function wireless-wlan group wifi-wake-host
pin 1 (gpio0-1): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 2 (gpio0-2): (MUX UNCLAIMED) gpio0:2
pin 3 (gpio0-3): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 4 (gpio0-4): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 5 (gpio0-5): (MUX UNCLAIMED) gpio0:5
pin 6 (gpio0-6): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 7 (gpio0-7): (MUX UNCLAIMED) gpio0:7
pin 8 (gpio0-8): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 9 (gpio0-9): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 10 (gpio0-10): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 11 (gpio0-11): ff050000.i2c (GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 12 (gpio0-12): ff050000.i2c (GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 13 (gpio0-13): (MUX UNCLAIMED) (GPIO UNCLAIMED)
二.从用户层控制gpio
要从用户层控制gpio前提是这个引脚是gpio或者已经复用为gpio
gpio bank:
RK3568 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0-A7、B0-B7、 C0-C7、 D0-D7 作为编号区分,常用以下公式计算引脚:
GPIO 引脚计算公式:pin = bank 32 + number
GPIO 小组编号计算公式:number = group 8 + X
下面演示 GPIO3_A7 引脚计算方法:
bank = 3; // GPIO3_A7 => 3, bank ∈ [0,4]
group = 0; // GPIO3_A7 => 0, group ∈ {(A=0), (B=1), (C=2), (D=3)}
X = 7; // GPIO3_A7 => 7, X ∈ [0,7]
GPIO3_A7 对应的设备树属性描述为:<&gpio3 7 IRQ_TYPE_EDGE_RISING>由kernel/include/dt-bindings/pinctrl/rockchip.h的宏定义可知。
gpiochipX:
当前SOC 一共包含5 个 GPIO 控制器,分别是:GPIO1,GPIO2,GPIO3,GPIO4,GPIO5。在这里,分别是gpiochip0 、gpiochip32 、gpiochip64 、gpiochip96 、gpiochip128 这5个文件夹,每个gpiochipX 文件夹用来管理一组GPIO。
export:
export用于将指定编号的GPIO 引脚导出。在使用GPIO 引脚之前,需要将其导出,导出成功之后才能使用它。注意export 文件是只写文件,不能读取,将一个指定的编号写入到export 文件中即可将对应的GPIO 引脚导出,例如:
echo 0 > export #导出编号为0的GPIO 引脚。对应当前SOC,也就是GPIO1_IO0。
导出成功之后会发现在/sys/class/gpio 目录下生成了一个名为gpio0 的文件夹(gpioX, X 表示对应的编号)。这个文件夹就是导出来的GPIO 引脚对应的文件夹,用于管理、控制该GPIO 引脚。
unexport:
unexport将导出的GPIO 引脚删除。当使用完GPIO 引脚之后,我们需要将导出的引脚删除,同样该文件也是只写、不可读的。例如:1
echo 0 > unexport # 删除导出的编号为0的GPIO 引脚1
删除成功之后,之前生产的gpio0 文件夹就会消失。
导出引脚echo export:
向/sys/class/gpio/export写入此编号,比如10号引脚,在shell中可以通过以下命令实现,1
echo 10 > /sys/class/gpio/export
命令成功后生成/sys/class/gpio/gpio10目录,
如果没有出现相应的目录,说明此引脚不可导出。
设置gpio的direction:
direction文件,定义输入输入方向,可以通过下面命令定义为输出1
echo out > /sys/class/gpio/gpio10/direction
direction接受的参数:in, out,
三.内核空间控制gpio
Linux pinctrl 子系统:
复用gpio2 PB1为gpio功能:1
2
3
4
5
6cam {
/omit-if-no-ref/
cam_pow_en: cam-pow-en {
rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
上下拉配置:
//上拉
pcfg-pull-up
//下拉
pcfg-pull-down
linux gpio子系统:
gpio_request函数:
int gpio_request(unsigned gpio, const char *label);
gpio:要申请的gpio标号(可以通过gpio bank计算得来)。
label:要申请的gpio取的名字。
可通过cat /sys/kernel/debug/gpio 命令查看gpio是否申请成功。
gpio_free函数:
void gpio_free(unsigned gpio)
gpio:要释放的gpio标号。
gpio_direction_input函数:此函数用于设置某个GPIO为输入
int gpio_direction_input(unsigned gpio)
gpio:要设置为输入的GPIO标号
gpio_direction_output函数:此函数用于设置某个GPIO为输出
int gpio_direction_output(unsigned gpio, int value)
gpio:要设置为输出的GPIO标号
value:GPIO默认输出值
gpio_get_value函数:此函数用于获取某个GPIO的值(0或1)
int __gpio_get_value(unsigned gpio)
gpio:要获取的GPIO标号
gpio_set_value函数:此函数用于设置某个GPIO的值
void __gpio_set_value(unsigned gpio, int value)
gpio:要设置的GPIO标号
value:要设置的值
驱动示例
下面就是一个简单的驱动,可放在rk3568/drivers/gpio/gpio-e.c
编译时,别忘了加上makefile
1 | # rk3568/kernel/drivers/gpio/Makefile |
c代码
1 |
|
3 对应的DTS
1 | gpio:e-gpio{ |
整体功能比较简单,唯一需要解释的是period-ms,这代表开机时先把gpio拉高/低一段时间(如例子中为15ms),然后释放掉对应的gpio资源。