Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Управление GPIO на Linux
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
vgovseychuk
Добрый день!

Меня интересует возможность управления gpio из linux.
По идее GPIO сначала нужно экспортировать, но как узнать, какой пин нужно экспортировать? Например, я хочу вывести 1 на 28-ой пин 3-его порта. При этом не хочется помнить, что GPIO3.28 - это включение питания USB.
Нельзя ли как-то дать понять системе, например через dts, что этот пин занят юзером и дать к нему доступ сразу, задав к тому же прерывания от этого пина или дефолтное состояние?

Ну и код dts для примера. Led-ы работают сразу через /sys/class/leds , а вот gpio нет.
Код
    gpio {
        compatible = "mygpio";
        pinctrl-names = "default";
        pinctrl-0 = <&gpio_pins_3V3>;
        gpio_USBHOST_VCCEN {
            label = "usbvccen";
            gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
            default-state = "on";
        };
    };
    leds {
        compatible = "gpio-leds";
        pinctrl-names = "default";
        pinctrl-0 = <&leds_pins>;
        power {/* POWER */
            label = "power";
            gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
            default-state = "on";
        };
        status {/* ACT */
            label = "status";
            gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
            default-state = "on";
        };
    };

Спасибо!
shamrel
Действительно. Перед началом работы с GPIO из userspace, соответствующий вывод должен быть прописан в DTS. Это нужно для того, что бы ядро знало, что с этой ножкой нужно/можно работать через gpio-драйвер.
Я это делаю так:

CODE
usergpio_pins: pinmux_usergpio_pins {
pinctrl-single,pins = <

/*button*/
0x05C (PIN_INPUT_PULLUP | MUX_MODE7) /* SW1 gpmc_a7.gpio1_23 MODE7 */
/*Vif vif_12v_fixed*/
0x16C (PIN_OUTPUT_PULLUP | MUX_MODE7) /* uart0_rtsn.gpio1_9 MODE7 */
/*3V3_plc vif_3v3_plc_fixed*/
0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_aclkx.gpio3_14 MODE7 */

>;
};

Соответственно, потом указатель на usergpio_pins помещаю в секцию pinmux.
Собственно, для процессора из примера MUX_MODE7 -- режим работы вывода процесса, соответствующий GPIO. Что такое PIN_INPUT_PULLUP и PIN_OUTPUT_PULLDOWN, думаю, понятно и так.
Единственная проблема с адресом. Это нужно смотреть документацию на процессор. Причем, следует отметить, что используется не абсолютный адрес, о смещение относительно блока pinmux.

Как работать с этим в userspace. Допустим, хотим вывести 1 в gpio1.9. (объявлен в примере).

1. Инициализируем устройство gpio1.9:

echo 41 > /sys/class/gpio/export

Тонкий вопрос, как gpio1.9 превратился в 41 ?. В процессоре параллельные порты объединены в 32-битную шину. В обозначении gpio1.9 первая цифра "1" -- номер порта, вторая -- номер ножки в порту. Таким образом, абсолютный номер порта будет 32 + 9 = 41.

2. Устанавливаем направление порта.
После экспорта в директории /sys/class/gpio/ появляется директория gpio41. Там много чего интересного, но сейчас нам нужен файл direction. Записываем туда направление.

echo "out" > /sys/class/gpio/gpio41/direction

Понятно, что для входа, значение будет "in".

3. Устанавливаем уровень.
Теперь, через запись в файл value значения, мы управляем выводом:

echo "1" > /sys/class/gpio/gpio41/value

P.S.: в командах могут быть ошибки, под рукой нет боевой системы.


vgovseychuk
Большое спасибо за разъяснения. А можно ли, допустим, назвать пин UsbOnGpio, и потом с ним работать из линукса, не экспортируя его каждый раз и не вспоминая, что же такое у нас GPIO125 ?
shamrel
Цитата(vgovseychuk @ Jan 21 2016, 13:11) *
Большое спасибо за разъяснения. А можно ли, допустим, назвать пин UsbOnGpio, и потом с ним работать из линукса, не экспортируя его каждый раз и не вспоминая, что же такое у нас GPIO125 ?

В Linux можно все, но не всегда целесообразно, а затраченные усилия, порой, не пропорциональны результату.
В своей практике, я в ПО, будь оно на Си или на Bash, порты описывал просто константами. Если проект объемный, то делал конфигурационный файл с настройками.
Если вам хочется рулить ножками руками из юзерспейса, то создайте скрипты.
В большинстве своем, достаточно редко приходится работать с линиями через драйвер GPIO, обычно к линиям, подключены какие-либо устройства, это описывается в Device Tree, и в системе уже можно работать с драйвером устройства, а не GPIO.
А вообще, если мне не изменяет память, посмотреть назначения GPIO можно где-то в /sys/kernel/debug/gpio . Считать файл, да распарсить.
alx2
Цитата(vgovseychuk @ Jan 21 2016, 14:34) *
По идее GPIO сначала нужно экспортировать, но как узнать, какой пин нужно экспортировать?
shamrel в-основном уже ответил(а), а я дополню, что номер gpio, которому соответствует ваш пин, может быть разным в разных версиях линукса. Я наступил на эти грабли, когда после апгрейда линукса устройство перестало работать - оказалось, что вся нумерация сдвинулась на 32. Сейчас в программе стоит проверка версии ядра.

Цитата(vgovseychuk @ Jan 21 2016, 14:34) *
Например, я хочу вывести 1 на 28-ой пин 3-его порта. При этом не хочется помнить, что GPIO3.28 - это включение питания USB.
Нельзя ли как-то дать понять системе, например через dts, что этот пин занят юзером и дать к нему доступ сразу, задав к тому же прерывания от этого пина или дефолтное состояние?
Как Вам вариант сделать это в инит-скрипте? Пропишите там
Код
echo 96 >/sys/clagg/gpio/export
... и т.д. ...
и будет ваш пин экспортироваться и настраиваться сразу при старте вашего устройства...
Про прерывание я не понял. Что за прерывание может быть от сигнала включения питания USB, если это выход, и ваша программа сама выдает в него сигналы? Какого рода события на этом пине Вы ожидаете?

И уж если Вы непременно хотите, чтобы при старте линукса пин сразу оказывался доступен без каких-либо дополнительных действий, что мешает объявить его как LED и работать с ним через /sys/class/leds, раз уж Вы говорите, что
Цитата(vgovseychuk @ Jan 21 2016, 14:34) *
Led-ы работают сразу через /sys/class/leds , а вот gpio нет.

Эдди
Через sys будет крайне медленно, если нужна скорость, понадобится ПДП. К сожалению, это требует рутовских прав (т.к. только он может с /dev/mem работать).
Но все ОК, я на "малинке" сделал так управление железякой.
Tarbal
Цитата(Эдди @ Jan 22 2016, 15:55) *
Через sys будет крайне медленно, если нужна скорость, понадобится ПДП. К сожалению, это требует рутовских прав (т.к. только он может с /dev/mem работать).
Но все ОК, я на "малинке" сделал так управление железякой.


Круто!
Я мои первые спектрографы на 8080 автоматизировал. На ассемблере писал в кооперативе "Поиск".
Эдди
А я с пиков начал, потом перешел на нормальные мелкоконтроллеры (STM8, STM32), а совсем уж элементарные системы, где хватит < десятка ног и не нужно всяких хитрых интерфейсов стал на одноплатниках делать — так проще и компактней.
Tarbal
Цитата(Эдди @ Jan 22 2016, 22:57) *
А я с пиков начал, потом перешел на нормальные мелкоконтроллеры (STM8, STM32), а совсем уж элементарные системы, где хватит < десятка ног и не нужно всяких хитрых интерфейсов стал на одноплатниках делать — так проще и компактней.


На пиках я уже устройства для массового производства делал, но это потом было.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.