Linux GPIO 数字如何获取它们的值?
How do Linux GPIO numbers get their values?
我想了解 Linux GPIO 数字如何获得它们的值。
例如GPIO mapping for Joule.
我尝试阅读 linux 有关 Pinctrl 子系统的文档,还查看了 Intel Joule 中使用的 GPIO 驱动程序的代码:
https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-broxton.c
然而,这种方式看起来非常特定于平台。我正在寻找一些通用的行业标准。请帮助或请指导我一些好文章。
首先,必须了解 全局系统 GPIO 编号 (GSGN) 与特定 GPIO 控制器的区别。早些时候,在 GPIO 描述符时代之前,已经使用了 GSGN。切换到描述符方案后,编号方案从(半)静态 GSGN 变为动态编号方案,因此对用户来说毫无意义。取而代之的是引脚标签(如果有)或一对 GPIO 控制器句柄,其编号为 relative 已被使用。这是由资源提供者决定的,例如 ACPI 和设备树。如果出于某种原因,用户想要获得一对控制器和相关编号,libgpiod 库和工具提供了实现此目的的可能性。
所以,link 到焦耳 GPIO 编号方案真的很脆弱,用户不应该知道 GSGN。在 运行 系统上有多种方法可以获取控制器和相关编号。但通常它都与驱动程序和 ACPI 表有关,不需要任何用户参与。
示例:
考虑引脚 UART_1_TXD
(出于某种原因,它在该文档中的命名有误,应该是 LPSS_UART1_TXD
)。根据 pinctrl-broxton.c 这是具有 ACPI _HID INT34D1 和 _UID 1[=55 的 GPIO 控制器上的引脚 43 =].
列出所有枚举的 GPIO 控制器(可选步骤):
# gpiodetect
gpiochip0 [INT34D1:00] (83 lines)
gpiochip1 [INT34D1:01] (72 lines)
gpiochip2 [INT34D1:02] (42 lines)
gpiochip3 [INT34D1:03] (31 lines)
gpiochip4 [INT34D1:04] (20 lines)
找一个 _UID 1:
# grep -w 1 /sys/bus/acpi/devices/INT34D1\:0*/uid
/sys/bus/acpi/devices/INT34D1:00/uid:1
# gpiodetect | grep -w INT34D1:00
gpiochip0 [INT34D1:00] (83 lines)
所以,有趣的一对是:gpiochip0 43
。
在实际的资源提供者中它看起来像这样(取自 meta-acpi 项目):
...
* pin name pin number led
* -----------------------------------------
* ISH_GPIO_0_LS 35 heartbeat
* ISH_GPIO_1_LS 33 sd-card
* ISH_GPIO_2_LS 31 wifi
* ISH_GPIO_3_LS 29 led-3
...
GpioIo (
...
"\_SB.GPO2", // GPIO controller
0) // Must be 0
{
22, // ISH_GPIO_0_LS
23, // ISH_GPIO_1_LS
24, // ISH_GPIO_2_LS
25 // ISH_GPIO_3_LS
}
...
在这里您可以看到通过完整路径引用 Device 对象,即 \_SB.GPO2.
您可以在 meta-acpi 项目中找到更多示例。
如果在任何奇怪的情况下用户真的想要一个无意义的数字,就是这样:
# mount -t debugfs none /sys/kernel/debug/
# cat /sys/kernel/debug/pinctrl/INT34D1\:00/gpio-ranges
GPIO ranges handled:
0: INT34D1:00 GPIOS [429 - 460] PINS [0 - 31]
32: INT34D1:00 GPIOS [461 - 492] PINS [32 - 63]
64: INT34D1:00 GPIOS [493 - 511] PINS [64 - 82]
# echo $((43-32+461))
472
有关 GPIO 库和子系统的更多详细信息,请参阅 GPIO in-kernel documentation。
我想了解 Linux GPIO 数字如何获得它们的值。 例如GPIO mapping for Joule.
我尝试阅读 linux 有关 Pinctrl 子系统的文档,还查看了 Intel Joule 中使用的 GPIO 驱动程序的代码: https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-broxton.c
然而,这种方式看起来非常特定于平台。我正在寻找一些通用的行业标准。请帮助或请指导我一些好文章。
首先,必须了解 全局系统 GPIO 编号 (GSGN) 与特定 GPIO 控制器的区别。早些时候,在 GPIO 描述符时代之前,已经使用了 GSGN。切换到描述符方案后,编号方案从(半)静态 GSGN 变为动态编号方案,因此对用户来说毫无意义。取而代之的是引脚标签(如果有)或一对 GPIO 控制器句柄,其编号为 relative 已被使用。这是由资源提供者决定的,例如 ACPI 和设备树。如果出于某种原因,用户想要获得一对控制器和相关编号,libgpiod 库和工具提供了实现此目的的可能性。
所以,link 到焦耳 GPIO 编号方案真的很脆弱,用户不应该知道 GSGN。在 运行 系统上有多种方法可以获取控制器和相关编号。但通常它都与驱动程序和 ACPI 表有关,不需要任何用户参与。
示例:
考虑引脚 UART_1_TXD
(出于某种原因,它在该文档中的命名有误,应该是 LPSS_UART1_TXD
)。根据 pinctrl-broxton.c 这是具有 ACPI _HID INT34D1 和 _UID 1[=55 的 GPIO 控制器上的引脚 43 =].
列出所有枚举的 GPIO 控制器(可选步骤):
# gpiodetect
gpiochip0 [INT34D1:00] (83 lines)
gpiochip1 [INT34D1:01] (72 lines)
gpiochip2 [INT34D1:02] (42 lines)
gpiochip3 [INT34D1:03] (31 lines)
gpiochip4 [INT34D1:04] (20 lines)
找一个 _UID 1:
# grep -w 1 /sys/bus/acpi/devices/INT34D1\:0*/uid
/sys/bus/acpi/devices/INT34D1:00/uid:1
# gpiodetect | grep -w INT34D1:00
gpiochip0 [INT34D1:00] (83 lines)
所以,有趣的一对是:gpiochip0 43
。
在实际的资源提供者中它看起来像这样(取自 meta-acpi 项目):
...
* pin name pin number led
* -----------------------------------------
* ISH_GPIO_0_LS 35 heartbeat
* ISH_GPIO_1_LS 33 sd-card
* ISH_GPIO_2_LS 31 wifi
* ISH_GPIO_3_LS 29 led-3
...
GpioIo (
...
"\_SB.GPO2", // GPIO controller
0) // Must be 0
{
22, // ISH_GPIO_0_LS
23, // ISH_GPIO_1_LS
24, // ISH_GPIO_2_LS
25 // ISH_GPIO_3_LS
}
...
在这里您可以看到通过完整路径引用 Device 对象,即 \_SB.GPO2.
您可以在 meta-acpi 项目中找到更多示例。
如果在任何奇怪的情况下用户真的想要一个无意义的数字,就是这样:
# mount -t debugfs none /sys/kernel/debug/
# cat /sys/kernel/debug/pinctrl/INT34D1\:00/gpio-ranges
GPIO ranges handled:
0: INT34D1:00 GPIOS [429 - 460] PINS [0 - 31]
32: INT34D1:00 GPIOS [461 - 492] PINS [32 - 63]
64: INT34D1:00 GPIOS [493 - 511] PINS [64 - 82]
# echo $((43-32+461))
472
有关 GPIO 库和子系统的更多详细信息,请参阅 GPIO in-kernel documentation。