Как программно использовать драйвер GPIO Expander в Linux?
Я пытаюсь настроить свой дистрибутив yocto Linux для установки двух встроенных I2C GPIO Expanders и документировать, как получить к ним программный доступ (например, из пользовательского приложения C). Оба GPIO Expanders - это NXP PCA9557, который поддерживается драйвером ядра gpio-pca953x.c:
https://github.com/torvalds/linux/blob/master/drivers/gpio/gpio-pca953x.c
Я понимаю, как скомпилировать этот драйвер в ядро (с помощью элемента конфигурации CONFIG_GPIO_PCA953X) и загрузить его (с помощью modprobe). Я также понимаю, что могу создать экземпляры этих двух устройств I2C в дереве устройств (это встроенное устройство, поэтому расширители GPIO статичны и неизменны):
gpio@20 {
compatible = "nxp,pca9557";
reg = <0x1a>;
gpio-controller;
#gpio-cells = <2>;
};
Мне не хватает информации, как использовать драйвер pca953x с этими созданными устройствами? Нужно ли мне связывать эти устройства с этим конкретным драйвером? Какие API-интерфейсы я использую для доступа к ним в пользовательском приложении, написанном на C? Они действуют как обычные GPIO, если я их правильно настроил?
Я более чем счастлив прочитать любую соответствующую документацию, длинную или нет, о том, как это сделать. Я просто новичок в драйверах для устройств Linux и понятия не имею, что делать дальше, несмотря на то, что много гуглил.
2 ответа
При правильной работе водитель должен обеспечитьgpiochipX
устройство в/dev
. Это можно использовать с вызовами ioctl.
The библиотека предоставляет дружественный API для взаимодействия с этими устройствами.
Установитеlibgpiod
пакет в Yocto. Он поставляется с некоторыми удобными инструментами командной строки для отладки.
gpiodetect — список всех присутствующих в системе gpiochips, их названия, метки и количество линий GPIO
gpioinfo - список всех линий указанных gpiochips, их имена, потребители, направление, активное состояние и дополнительные флаги
gpioget - чтение значений указанных линий GPIO
gpioset - установить значения указанных линий GPIO, потенциально сохранить линии экспортированными и дождаться тайм-аута, пользовательского ввода или сигнала
gpiofind — найти имя gpiochip и смещение строки по имени строки
gpiomon — ждать событий на линиях GPIO, указывать какие события смотреть, сколько событий обрабатывать перед выходом или нужно ли о событиях сообщать в консоль
Если у вас нет файла, значит драйвер не запустился. Проверятьdmesg
для подсказок.
# dmesg | grep pca953x
[ 0.208762] pca953x 1-0020: using AI
Вы также можете проверить, доступен ли чип pca на i2c. Перечислите шины i2c и узнайте, на какой из них работает pca9557.
# i2cdetect -l
i2c-0 21a0000.i2c
i2c-1 21a4000.i2c
i2c-2 21a8000.i2c
Допустим, микросхема PCA находится на шине i2c-1. Обнаружение устройств на шине.
# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Таблица должна содержать
-
UU
по адресу 1a, если работает драйвер pca953x, - по адресу 1a, если драйвер не запущен, но чип работает и им можно управлять по i2c,
-
--
по адресу 1a, если чип выключен или его адрес i2c на самом деле не1a
.
Есть несколько способов управления GPIO из пользовательского пространства, но что вы пытаетесь контролировать? Linux может использовать GPIO как светодиод, кнопку, прерывание и многое другое.
sysfs - это «старый» способ управления GPIO. Он работает и до сих пор поддерживается. По сути, вы пишете узлы в каталоге / sys. Запись файлов в C.Простой процесс на C. Вы можете сначала протестировать запись в файл из Shell, если хотите.
$ echo 7 > /sys/class/gpio/export
$ echo "out" > /sys/class/gpio/gpio7/direction
$ echo 1 > /sys/class/gpio/gpio7/value #turn on
$ echo 0 > /sys/class/gpio/gpio7/value #turn off
Есть более новый способ доступа к GPIO. Вы можете открыть / dev / chip и сделать несколько вызовов IOCTL. Включают
#include <linux/gpio.h>
тогда
-
GPIO_GET_LINEHANDLE_IOCTL
, чтобы увидеть текущий статус -
GPIOHANDLE_GET_LINE_VALUES_IOCTL
затем читать -
GPIOHANDLE_SET_LINE_VALUES_IOCTL
написать
Вы можете проверить это с помощью программы Shell, которая использует тот же интерфейс.
$ gpiodetect
$ gpioinfo
$ gpioset
Я никогда этого не делал, но вот пример инструмента , который это делает. Также в ядре новее 5.9 вы могли использовать
#include "gpio-utils.h"
.