Автор Тема: поддержка GPIO  (Прочитано 367 раз)

Оффлайн Olej

поддержка GPIO
« : Июнь 11, 2018, 04:15:51 pm »
Железка - Orange Pi One.
Образ Armbian - Armbian Stretch mainline kernel 4.14.y ... с пересобранным их же SDK ядром, но это дела не меняет:
root@orangepione:~# uname -a
Linux orangepione 4.14.48-sunxi #1 SMP Wed Jun 6 19:14:27 EEST 2018 armv7l GNU/Linux
В загруженной систем нет поддержки GPIO:
olej@orangepione:~$ lsmod | grep gpio
root@orangepione:~# modinfo gpio-sunxi
modinfo: ERROR: Module gpio-sunxi not found.

root@orangepione:~# modprobe gpio-sunxi
modprobe: FATAL: Module gpio-sunxi not found in directory /lib/modules/4.14.48-sunxi
Вопросы ... для начала ;) :
1. Поддержка GPIO не включена в образе по умолчанию?
2. Что нужно сделать чтобы загрузить модуль gpio-sunxi? Что и где нужно взять?

Оффлайн Olej

Re: поддержка GPIO
« Ответ #1 : Июнь 11, 2018, 04:46:46 pm »
olej@orangepione:~$ lsmod | grep gpio
...
1. Поддержка GPIO не включена в образе по умолчанию?
Тогда как понимать следующее? :
olej@orangepione:~$ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 июн 11 15:46 export
lrwxrwxrwx 1 root root    0 июн 11 15:46 gpiochip0 -> ../../devices/platform/soc/1c20800.pinctrl/gpio/gpiochip0
lrwxrwxrwx 1 root root    0 июн 11 15:46 gpiochip352 -> ../../devices/platform/soc/1f02c00.pinctrl/gpio/gpiochip352
--w------- 1 root root 4096 июн 11 15:46 unexport
Напишу скриптик gpio.tst :
olej@orangepione:~$ cat gpio.tst
for v in 1 2 3 4 5 6 7 8 9 10 11 12; do echo "$v" > /sys/class/gpio/export ; done

olej@orangepione:~$ sudo ./gpio.tst

olej@orangepione:~$ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 июн 11 16:39 export
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio1 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio1
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio10 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio10
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio11 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio11
lrwxrwxrwx 1 root root    0 июн 11 16:39 gpio12 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio12
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio2 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio2
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio3 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio3
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio4 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio4
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio5 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio5
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio6 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio6
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio7 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio7
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio8 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio8
lrwxrwxrwx 1 root root    0 июн 11 16:40 gpio9 -> ../../devices/platform/soc/1c20800.pinctrl/gpiochip0/gpio/gpio9
lrwxrwxrwx 1 root root    0 июн 11 15:46 gpiochip0 -> ../../devices/platform/soc/1c20800.pinctrl/gpio/gpiochip0
lrwxrwxrwx 1 root root    0 июн 11 15:46 gpiochip352 -> ../../devices/platform/soc/1f02c00.pinctrl/gpio/gpiochip352
--w------- 1 root root 4096 июн 11 15:46 unexport
Всё появилось... Каким это образом?
root@orangepione:~# echo out > /sys/class/gpio/gpio12/direction

root@orangepione:~# echo 1 > /sys/class/gpio/gpio12/value

root@orangepione:~# echo $?
0
Осциллографом ногу 12 не проверял ... всему своё время - но система считает что всё нормально, по коду ошибки...
« Последнее редактирование: Июнь 11, 2018, 04:51:40 pm от Olej »

Оффлайн Olej

Re: поддержка GPIO
« Ответ #2 : Июнь 11, 2018, 04:50:19 pm »
olej@orangepione:~$ lsmod | grep gpio
С помощью кого из них осуществляется поддержка GPIO на уровне общих стандартов Linux:
olej@orangepione:~$ lsmod
Module                  Size  Used by
snd_soc_hdmi_codec     16384  1
rc_cec                 16384  0
dw_hdmi_i2s_audio      16384  0
dw_hdmi_cec            16384  0
sun8i_codec_analog     24576  0
snd_soc_simple_card    16384  0
snd_soc_simple_card_utils    16384  1 snd_soc_simple_card
sun4i_i2s              16384  2
snd_soc_core          118784  5 sun4i_i2s,sun8i_codec_analog,snd_soc_hdmi_codec,snd_soc_simple_card_utils,snd_soc_simple_card
snd_pcm_dmaengine      16384  1 snd_soc_core
snd_pcm                65536  4 sun4i_i2s,snd_pcm_dmaengine,snd_soc_hdmi_codec,snd_soc_core
joydev                 20480  0
input_leds             16384  0
evdev                  20480  0
sun8i_dw_hdmi          16384  0
dw_hdmi                28672  2 dw_hdmi_i2s_audio,sun8i_dw_hdmi
sun4i_gpadc_iio        16384  0
snd_timer              24576  1 snd_pcm
sun8i_mixer            16384  0
cec                    40960  2 dw_hdmi_cec,dw_hdmi
snd                    45056  4 snd_soc_hdmi_codec,snd_timer,snd_soc_core,snd_pcm
soundcore              16384  1 snd
sun4i_tcon             20480  1 sun8i_dw_hdmi
uio_pdrv_genirq        16384  0
uio                    16384  1 uio_pdrv_genirq
sun4i_drm              16384  0
ip_tables              20480  0
x_tables               20480  1 ip_tables

Оффлайн Olej

Re: поддержка GPIO
« Ответ #3 : Июнь 11, 2018, 05:01:03 pm »
Установил WiringOP ... как пишут здесь: Установка и настройка WiringOP/WiringPi на Orange Pi PC (и ещё во множестве сходных мест)
Цитировать
08.11.2016
Orange Pi проекты
olej@orangepione:~/WiringOP$ gpio -v
gpio version: 2.20
Copyright (c) 2012-2014 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Banana Pro Details:
  Type: Banana Pro, Revision: 1.2, Memory: 1024MB, Maker: LeMaker
olej@orangepione:~/WiringOP$ gpio readall
 +-----+-----+----------+------+---+-Orange Pi+---+---+------+---------+-----+--+
 | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 |     |     |     3.3v |      |   |  1 || 2  |   |      | 5v       |     |     |
 |  12 |   8 |    SDA.0 | ALT3 | 0 |  3 || 4  |   |      | 5V       |     |     |
 |  11 |   9 |    SCL.0 | ALT3 | 0 |  5 || 6  |   |      | 0v       |     |     |
 |   6 |   7 |   GPIO.7 | ALT3 | 0 |  7 || 8  | 0 | ALT3 | TxD3     | 15  | 13  |
 |     |     |       0v |      |   |  9 || 10 | 0 | ALT3 | RxD3     | 16  | 14  |
 |   1 |   0 |     RxD2 | ALT3 | 0 | 11 || 12 | 0 | ALT3 | GPIO.1   | 1   | 110 |
 |   0 |   2 |     TxD2 | ALT3 | 0 | 13 || 14 |   |      | 0v       |     |     |
 |   3 |   3 |     CTS2 | ALT3 | 0 | 15 || 16 | 0 | ALT3 | GPIO.4   | 4   | 68  |
 |     |     |     3.3v |      |   | 17 || 18 | 0 | ALT3 | GPIO.5   | 5   | 71  |
 |  64 |  12 |     MOSI | ALT3 | 0 | 19 || 20 |   |      | 0v       |     |     |
 |  65 |  13 |     MISO | ALT3 | 0 | 21 || 22 | 0 | ALT3 | RTS2     | 6   | 2   |
 |  66 |  14 |     SCLK | ALT3 | 0 | 23 || 24 | 0 | ALT3 | CE0      | 10  | 67  |
 |     |     |       0v |      |   | 25 || 26 | 0 | ALT3 | GPIO.11  | 11  | 21  |
 |  19 |  30 |    SDA.1 | ALT3 | 0 | 27 || 28 | 0 | ALT3 | SCL.1    | 31  | 18  |
 |   7 |  21 |  GPIO.21 | ALT3 | 0 | 29 || 30 |   |      | 0v       |     |     |
 |   8 |  22 |  GPIO.22 | ALT3 | 0 | 31 || 32 | 0 | ALT3 | RTS1     | 26  | 200 |
 |   9 |  23 |  GPIO.23 | ALT3 | 0 | 33 || 34 |   |      | 0v       |     |     |
 |  10 |  24 |  GPIO.24 | ALT3 | 0 | 35 || 36 | 0 | ALT3 | CTS1     | 27  | 201 |
 |  20 |  25 |  GPIO.25 | ALT3 | 0 | 37 || 38 | 0 | ALT3 | TxD1     | 28  | 198 |
 |     |     |       0v |      |   | 39 || 40 | 0 | ALT3 | RxD1     | 29  | 199 |
 +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 +-----+-----+----------+------+---+-Orange Pi+---+------+----------+-----+-----+

Как я понял (или разуверьте меня ;D):
1. WiringOP является библиотекой пространства пользователя...
2. Для её работы, вообще говоря, не нужна поддержка со стороны модуля ядра, может работать без драйвера ... добираясь куда-то по портам GPIO напрямую, пользуясь стандартом на железо GPIO
3. Но из-за этого оно не может работать по прерываниям (на вход GPIO) - только программным опросом (циклическим, как работают программируемые логические контроллеры, PLC).

Оффлайн Olej

Re: поддержка GPIO
« Ответ #4 : Июнь 11, 2018, 06:34:06 pm »
Всё появилось... Каким это образом?
Простой, но достаточный рассказ "на пальцах" как работает стандарт (драйвер) GPIO Linux: Linux: кнопки, светодиоды и GPIO.
Цитировать
Начиная с версии 2.6.26 (кажется) у Linux появляется стандартный интерфейс для работы с GPIO через sysfs.
...
Главной точкой работы с GPIO является директория /sys/class/gpio.

(самое главное здесь выделил - это я)
Пример (это уже Armbian):
olej@orangepione:~$ tree /sys/class/gpio/gpio1/
/sys/class/gpio/gpio1/
├── active_low
├── device -> ../../../gpiochip0
├── direction
├── edge
├── power
│   ├── autosuspend_delay_ms
│   ├── control
│   ├── runtime_active_time
│   ├── runtime_status
│   └── runtime_suspended_time
├── subsystem -> ../../../../../../../class/gpio
├── uevent
└── value

3 directories, 10 files

olej@orangepione:~$ cat /sys/class/gpio/gpio1/active_low
0

olej@orangepione:~$ cat /sys/class/gpio/gpio1/edge
none

Здесь же становится ясным все ограничения, которые будут возникать в любой подсистеме, работающей с GPIO в пространстве пользователя...
3. Но из-за этого оно не может работать по прерываниям (на вход GPIO) - только программным опросом (циклическим, как работают программируемые логические контроллеры, PLC).
Цитировать
Хорошо, теперь мы может узнать, нажата кнопка или нет, просто прочитав значение из value. Но удобно ли это? Скорее всего — нет. Нам придется постоянно, с некоторой периодичностью считывать текущее значение (данная технология называется polling), чтобы определить момент, когда кнопка будет нажата. Лишняя работа – лишняя трата ресурсов. Большинство производителей SoC’ов снабжают свои GPIO контроллером прерываний, который генерирует прерывание по всяким различным случаям: изменение уровня, установка уровня в высокое или низкое состояние. Можно ли это как-то использовать через sysfs? Документация, сообщает, что можно. Для этого, нам необходимо в файл edge записать одно из следующих значений: none, rising, falling или both. Здесь: none – выключаем отслеживание изменения состояния входящей линии; rising и falling – отслеживаем переход из неактивного состояния в активное и из активного в неактивное соответственно; both – реагируем на любое изменение состояния.
Теперь всё становится на свои места...
« Последнее редактирование: Июнь 11, 2018, 07:19:15 pm от Olej »

Оффлайн Olej

Re: поддержка GPIO
« Ответ #5 : Июнь 11, 2018, 06:42:25 pm »
Простой, но достаточный рассказ "на пальцах" как работает стандарт (драйвер) GPIO Linux: Linux: кнопки, светодиоды и GPIO.

И описываются ещё некоторые не очевидные мелочи, на которые можно убить много времени:
Цитировать
Инструкция гласит, что стоит только установить одно из этих значений (кроме none), так сразу с помощью функции poll() или select() можно определить, изменялось ли состояние линии. В случае, если состояние не менялось, вызов read() для файла value должен быть заблокирован. Однако, тут есть тонкость. Если вы откроете файл value и попытаетесь натравить на него poll(), то получите, что чтение не будет блокироваться независимо от того, менялось состояние линии или нет.

Авторы подсистемы GPIO видимо хотели, чтобы cat value срабатывал всегда, независимо от того, что записано в файле edge, поэтому первое чтение не будет блокироваться никогда. В принципе, это логично: для того, чтобы отслеживать изменения нужно сначала определить изначальное состояние. Однако, мне пришлось потратить почти часа два, и только в каком-то заброшенном форуме я нашел предположение, почему poll() не срабатывает и что для этого можно сделать.

Я открывал файл value на каждое чтение и очень удивлялся, почему не происходит блокировка. Оказалось, что файл нужно открывать один раз за весь сеанс слежения за линией, читать из него начальное значение и только тогда, последующие операции чтения будут блокироваться до появления указанного в edge события. И тут тоже есть одна тонкость: значения из файла value читаются только по смещению 0, в то время как вызов функции read() изменяет позицию чтения. Поэтому, перед вызовом read() нужно сбросить позицию чтения с помощью lseek(). В документации Linux эти моменты почему-то обойдены.
И пример кода, который, я считаю, стоит чтобы его скопировать сюда:
Цитировать
Вот, как будет выглядеть чтение GPIO c использованием событий edge:
// set edge event on specific gpio_line
int gpio_edge_set(int n, const char *edge_str)
{
    char filename[PATH_MAX];
    FILE *file;

    snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/edge", n);
    file = fopen(filename, "w");
    if (file == NULL) return -1;
    fprintf(file, "%s\n", edge_str);
    fclose(file);

    return 0;
}

// set GPIO line polling mode
int gpio_poll(int n)
{
    char filename[PATH_MAX];
    int fd;
    char c;
    int err;

    snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/value", n);
    fd = open(filename, O_RDONLY);
    if (fd < 0) return -1;

    read(fd, &c, sizeof(c));

    return fd;
}

// get GPIO line value
int gpio_get(int fd, int timeout)
{
    struct pollfd pollfd[1];
    char c;
    int err;

    pollfd[0].fd = fd;
    pollfd[0].events = POLLPRI | POLLERR;
    pollfd[0].revents = 0;

    err =  poll(pollfd, 1, timeout);
    if(err != 1) return -1;

    lseek(fd, 0, SEEK_SET);
    err = read(fd, &c, sizeof(c));
    if(err != 1) return -1;

    return c - '0';
}

Оффлайн Olej

Re: поддержка GPIO
« Ответ #6 : Июнь 11, 2018, 06:57:53 pm »
Как я понял (или разуверьте меня ;D):
1. WiringOP является библиотекой пространства пользователя...
2. Для её работы, вообще говоря, не нужна поддержка со стороны модуля ядра, может работать без драйвера ... добираясь куда-то по портам GPIO напрямую, пользуясь стандартом на железо GPIO
3. Но из-за этого оно не может работать по прерываниям (на вход GPIO) - только программным опросом (циклическим, как работают программируемые логические контроллеры, PLC).
Таким образом, WiringOP годится для организации циклического программного опроса ... ещё это называют pooling, или моноцикл - когда WiringOP в цикле непрерывно молотит опрос входов GPIO.
Это в точности напоминает тот цикл автоматического управления, как это реализуется в Arduino или промышленных PLC (программируемых логических контроллерах ... Siemens, Schneider Electric ... и т.п.).

И WiringOP не годится для реакции на данные GPIO по прерываниям, по событиям... ну и таким образом, для организации многопоточной, параллельной работы и т.д.

Это не значит, что одно явно лучше другого или хуже.
Это разные способы.

P.S. Хотя ... работа через драйвер, в стандартной sysfs модели Linux полностью перекрывает возможности WiringOP, т.е. включает все те возможности, но не наоборот. Но и WiringOP имеет право жить, за счёт большей простоты своего использования из программного кода, там где это уместно.

Оффлайн ua3nbw

Re: поддержка GPIO
« Ответ #7 : Июнь 11, 2018, 07:43:37 pm »
И WiringOP не годится для реакции на данные GPIO по прерываниям, по событиям... ну и таким образом, для организации многопоточной, параллельной работы и т.д.
Да работают прерывания, тестил ещё на сборках лобориса  с WiringOP тут код : https://github.com/ua3nbw/gpiokey
isr и wfi это наше всё.

Оффлайн Olej

Re: поддержка GPIO
« Ответ #8 : Июнь 11, 2018, 07:59:33 pm »
И WiringOP не годится для реакции на данные GPIO по прерываниям, по событиям... ну и таким образом, для организации многопоточной, параллельной работы и т.д.
Да работают прерывания, тестил ещё на сборках лобориса  с WiringOP тут код : https://github.com/ua3nbw/gpiokey
isr и wfi это наше всё.
Без поддержки модуля ядра GPIO? с выгруженным драйвером?

Я не понимаю как из пространства пользователя можно ловить прерывания без ядерной части ... но посмотрю по свободе.

Оффлайн Olej

Re: поддержка GPIO
« Ответ #9 : Июнь 11, 2018, 08:07:13 pm »
Да работают прерывания, тестил ещё на сборках лобориса  с WiringOP тут код : https://github.com/ua3nbw/gpiokey
isr и wfi это наше всё.
Автор того проекта пишет (там же на странице):
Цитировать
This is a modified WiringPi for OrangePi. We call it WiringOP. Test fo Orangepi pc When doing menuconfig the appropriate setting can be found under Device Drivers -> GPIO Support -> sysfs interface, or use CONFIG_GPIO_SYSFS=y if manually editing .config.
Они просто используют WiringOP как прослойку к стандартному Linux интерфейсу sysfs, и ничего из этого не будет работать без загруженного драйвера чипа GPIO.

Оффлайн Olej

Re: поддержка GPIO
« Ответ #10 : Июнь 11, 2018, 08:12:35 pm »
Они просто используют WiringOP как прослойку к стандартному Linux интерфейсу sysfs, и ничего из этого не будет работать без загруженного драйвера чипа GPIO.
Ещё раз спрошу здесь (уже спрашивал в других темах!):
- как посмотреть информацию о конкретных периферийных чипах на шинах?...
- то, что в x86 десктопах делается командой lspci ...

То, что не удаётся посмотреть так:
olej@orangepione:~$ sudo lspci
pcilib: Cannot open /proc/bus/pci
lspci: Cannot find any working access method.

olej@orangepione:~$ ls /proc/bus
input
Понятно, нет такой шины. А что есть?

Оффлайн ua3nbw

Re: поддержка GPIO
« Ответ #11 : Июнь 11, 2018, 08:26:02 pm »
Ещё раз спрошу здесь (уже спрашивал в других темах!):
- как посмотреть информацию о конкретных периферийных чипах на шинах?...
- то, что в x86 десктопах делается командой lspci ...
Никак, в arm нет аналога lspci.

Оффлайн ua3nbw

Re: поддержка GPIO
« Ответ #12 : Июнь 11, 2018, 08:50:43 pm »

Без поддержки модуля ядра GPIO? с выгруженным драйвером?

Я не понимаю как из пространства пользователя можно ловить прерывания без ядерной части ... но посмотрю по свободе.

а, там при сборке ядра в конфиге надо  CONFIG_GPIO_SYSFS=y.

Оффлайн AlDemin

  • Житель
  • ****
  • Сообщений: 472
  • Лайков: 157
  • Карма: +23/-1
  • OPi, OPi+, OPiOne, OPiZero, OPiPC2, BPi, RPiB.
    • Просмотр профиля
Re: поддержка GPIO
« Ответ #13 : Июнь 11, 2018, 08:54:04 pm »
Цитата: Olej
Они просто используют WiringOP как прослойку к стандартному Linux интерфейсу sysfs, и ничего из этого не будет работать без загруженного драйвера чипа GPIO.
Я смотрел исходники WiringOP: что то работает через sysfs, но в основном напрямую с регистрами процессора в обход и без участия драйвера.

Оффлайн Olej

Re: поддержка GPIO
« Ответ #14 : Июнь 11, 2018, 09:06:49 pm »
Цитата: Olej
Они просто используют WiringOP как прослойку к стандартному Linux интерфейсу sysfs, и ничего из этого не будет работать без загруженного драйвера чипа GPIO.
Я смотрел исходники WiringOP: что то работает через sysfs, но в основном напрямую с регистрами процессора в обход и без участия драйвера.
Ну так вот всё, что связано с прерываниями - работает через sysfs, а всё, что не работает с прерываниями - работает напрямую с портами I/O.