Как числа GPIO в Linux получают свои значения? - PullRequest
1 голос
/ 05 апреля 2019

Я пытаюсь понять, как числа GPIO в Linux получают свои значения.например, Отображение GPIO для Джоуля .

Я попытался прочитать документацию по Linux в подсистеме Pinctrl, а также посмотрел код драйвера GPIO, используемого в Intel Joule: https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-broxton.c

Однако такой путь выглядит очень специфичным для платформы.Я ищу какой-то общий отраслевой стандарт.Пожалуйста, помогите или направьте меня к какой-нибудь хорошей статье.

1 Ответ

2 голосов
/ 08 апреля 2019

Прежде всего, нужно получить разницу между Глобальным системным номером GPIO (GSGN) и относительно определенного контроллера GPIO.Ранее, до эры дескрипторов GPIO, использовался GSGN.После переключения на схему дескриптора схема нумерации переходит от (полу) статического GSGN к динамическому и, таким образом, делает бессмысленным для пользователя.Вместо этого стала использоваться метка контакта, если он есть, или пара ручки контроллера GPIO с номером относительно .Это продиктовано поставщиками ресурсов, такими как ACPI и Device Tree.Если по какой-либо причине пользователь хочет получить пару контроллера и относительное число, библиотека и инструменты libgpiod дают возможность достичь этого.

Итак, ссылка на Joule GPIOСхема нумерации действительно хрупкая, пользователи не должны знать GSGN.Есть способы, как получить контроллер и относительный номер в работающей системе.Но обычно все это связано с таблицами драйверов и ACPI и не требует участия пользователя.

Пример:

Примите во внимание вывод UART_1_TXD (попо какой-то причине он указан в этом документе неправильно, должно быть LPSS_UART1_TXD).Согласно pinctrl-broxton.c это вывод 43 на контроллере GPIO с ACPI _HID INT34D1 и _UID 1 .

Список всех перечисленных контроллеров 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.txt.

...