Как программно использовать драйвер 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".

Другие вопросы по тегам