Перейти к содержанию
    

Управление GPIO на Linux

Добрый день!

 

Меня интересует возможность управления 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";
        };
    };

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Я это делаю так:

 

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.: в командах могут быть ошибки, под рукой нет боевой системы.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большое спасибо за разъяснения. А можно ли, допустим, назвать пин UsbOnGpio, и потом с ним работать из линукса, не экспортируя его каждый раз и не вспоминая, что же такое у нас GPIO125 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большое спасибо за разъяснения. А можно ли, допустим, назвать пин UsbOnGpio, и потом с ним работать из линукса, не экспортируя его каждый раз и не вспоминая, что же такое у нас GPIO125 ?

В Linux можно все, но не всегда целесообразно, а затраченные усилия, порой, не пропорциональны результату.

В своей практике, я в ПО, будь оно на Си или на Bash, порты описывал просто константами. Если проект объемный, то делал конфигурационный файл с настройками.

Если вам хочется рулить ножками руками из юзерспейса, то создайте скрипты.

В большинстве своем, достаточно редко приходится работать с линиями через драйвер GPIO, обычно к линиям, подключены какие-либо устройства, это описывается в Device Tree, и в системе уже можно работать с драйвером устройства, а не GPIO.

А вообще, если мне не изменяет память, посмотреть назначения GPIO можно где-то в /sys/kernel/debug/gpio . Считать файл, да распарсить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По идее GPIO сначала нужно экспортировать, но как узнать, какой пин нужно экспортировать?
shamrel в-основном уже ответил(а), а я дополню, что номер gpio, которому соответствует ваш пин, может быть разным в разных версиях линукса. Я наступил на эти грабли, когда после апгрейда линукса устройство перестало работать - оказалось, что вся нумерация сдвинулась на 32. Сейчас в программе стоит проверка версии ядра.

 

Например, я хочу вывести 1 на 28-ой пин 3-его порта. При этом не хочется помнить, что GPIO3.28 - это включение питания USB.

Нельзя ли как-то дать понять системе, например через dts, что этот пин занят юзером и дать к нему доступ сразу, задав к тому же прерывания от этого пина или дефолтное состояние?

Как Вам вариант сделать это в инит-скрипте? Пропишите там

echo 96 >/sys/clagg/gpio/export
... и т.д. ...

и будет ваш пин экспортироваться и настраиваться сразу при старте вашего устройства...

Про прерывание я не понял. Что за прерывание может быть от сигнала включения питания USB, если это выход, и ваша программа сама выдает в него сигналы? Какого рода события на этом пине Вы ожидаете?

 

И уж если Вы непременно хотите, чтобы при старте линукса пин сразу оказывался доступен без каких-либо дополнительных действий, что мешает объявить его как LED и работать с ним через /sys/class/leds, раз уж Вы говорите, что

Led-ы работают сразу через /sys/class/leds , а вот gpio нет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Через sys будет крайне медленно, если нужна скорость, понадобится ПДП. К сожалению, это требует рутовских прав (т.к. только он может с /dev/mem работать).

Но все ОК, я на "малинке" сделал так управление железякой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Через sys будет крайне медленно, если нужна скорость, понадобится ПДП. К сожалению, это требует рутовских прав (т.к. только он может с /dev/mem работать).

Но все ОК, я на "малинке" сделал так управление железякой.

 

Круто!

Я мои первые спектрографы на 8080 автоматизировал. На ассемблере писал в кооперативе "Поиск".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я с пиков начал, потом перешел на нормальные мелкоконтроллеры (STM8, STM32), а совсем уж элементарные системы, где хватит < десятка ног и не нужно всяких хитрых интерфейсов стал на одноплатниках делать — так проще и компактней.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я с пиков начал, потом перешел на нормальные мелкоконтроллеры (STM8, STM32), а совсем уж элементарные системы, где хватит < десятка ног и не нужно всяких хитрых интерфейсов стал на одноплатниках делать — так проще и компактней.

 

На пиках я уже устройства для массового производства делал, но это потом было.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...