Работа с GPIO/en: различия между версиями
Fizikdaos (обсуждение | вклад) (Новая страница: «Working with GPIO») |
|||
(не показано 59 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
<languages/> | <languages/> | ||
В Wiren Board часть GPIO выведена на клеммники, часть выведена на разъёмы UEXT, часть используется для служебных целей. | |||
GPIO | GPIO также используются для управления транзисторами для коммутации низковольтной нагрузки. | ||
Соответствие между номерами GPIO в Linux и их местоположением и функцией можно найти в табличке [[WB SH 3.5: Список GPIO|WB SH 3.5: Список GPIO]] или [[WB rev. 2.8: Список GPIO|WB rev. 2.8: Список GPIO]]. | |||
В Wiren Board rev. 2.8 8 GPIO на специальном разъёме подключены через [[Special:MyLanguage/MCP23S08|MCP23S08]] и временно не работают со стандартным Linux API. Описание работы с ними есть на странице [[Special:MyLanguage/MCP23S08|MCP23S08]]. | |||
<b> | <b> Все GPIO (как и остальные порты Wiren Board) работают с напряжением 3.3V. Ни в коем случае не подключайте к GPIO напрямую сигналы, напряжением больше 3.3V! В случае необходимости подключения устройств, работающих с более высоким напряжением, необходимо использовать схемы согласования или подключать (для 5V) через резистор в 20 кОм и более </b> | ||
На некоторых GPIO (в частности на 3х GPIO, выведенных на клеммники в Wiren Board rev. 2.8) можно программно установить 47к подтяжку к +3.3В. См. [[Special:MyLanguage/Pin_pull-up|Pin_pull-up]]. | |||
=== sysfs | ===Интерфейс sysfs в Linux === | ||
GPIO в Linux поддерживаются через sysfs-интерфейс. | |||
Для работы через sysfs c определённым GPIO его надо экспортировать: | |||
Здесь и далее N - номер gpio | |||
<pre> | <pre> | ||
Строка 25: | Строка 25: | ||
</pre> | </pre> | ||
Экспортированные gpio появляются в каталоге /sys/class/gpio : | |||
<pre> | <pre> | ||
Строка 38: | Строка 38: | ||
</pre> | </pre> | ||
В директории <b>/sys/class/gpioN</b> теперь находятся файлы для работы с GPIO (где N - номер GPIO, как и было сказано ранее): | |||
<pre> | <pre> | ||
Строка 52: | Строка 52: | ||
</pre> | </pre> | ||
Установка направления GPIO (ввод/вывод) производится с помощью записи в файл <b>direction</b> | |||
<pre> | <pre> | ||
echo in > /sys/class/gpio/gpioN/direction # | echo in > /sys/class/gpio/gpioN/direction # установим GPIO номер N на ввод | ||
echo out > /sys/class/gpio/gpioN/direction # | echo out > /sys/class/gpio/gpioN/direction # установим GPIO номер N на вывод | ||
</pre> | </pre> | ||
Чтение и установка значения GPIO производится с помощью файла <b>value</b>. | |||
Чтение: | |||
<pre> | <pre> | ||
echo in > /sys/class/gpio/gpioN/direction # | echo in > /sys/class/gpio/gpioN/direction # установим GPIO номер N на ввод | ||
cat /sys/class/gpio/gpioN/value # | cat /sys/class/gpio/gpioN/value # вернёт 1 или 0 | ||
</pre> | </pre> | ||
Запись: | |||
<pre> | <pre> | ||
echo out > /sys/class/gpio/gpioN/direction # | echo out > /sys/class/gpio/gpioN/direction # установим GPIO номер N на вывод | ||
echo 0 > /sys/class/gpio/gpioN/value # | echo 0 > /sys/class/gpio/gpioN/value # установим логический 0 (низкое напряжение) на GPIO номер N | ||
echo 1 > /sys/class/gpio/gpioN/value # | echo 1 > /sys/class/gpio/gpioN/value # установим логический 1 (высокое напряжение) на GPIO номер N | ||
</pre> | </pre> | ||
==== | ====Интерфейс sysfs и прерывания==== | ||
Через интерфейс sysfs можно запросить прерывания по изменению состояния процессора. | |||
Установка прерывания производится путём записи значения в файл "edge". Значения могут быть: | |||
* "none" - | * "none" - отключить прерывание | ||
* "rising" - | * "rising" - включить прерывание по нисходящему фронту | ||
* "falling" - | * "falling" - включить прерывание по восодящему фронту | ||
* "both" - | * "both" - включить прерывание по обеим фронтам. | ||
Пример: | |||
<pre> | <pre> | ||
root@wirenboard:~# echo 3 > /sys/class/gpio/export # | root@wirenboard:~# echo 3 > /sys/class/gpio/export # экспортируем GPIO номер 3 (TB10 на WB3.3) | ||
root@wirenboard:~# cat /sys/class/gpio/gpio3/edge # | root@wirenboard:~# cat /sys/class/gpio/gpio3/edge # проверяем состояние прерывания | ||
none | none | ||
root@wirenboard:~# echo falling > /sys/class/gpio/gpio3/edge # | root@wirenboard:~# echo falling > /sys/class/gpio/gpio3/edge # устанавливаем прерывание по нисходящему фронту | ||
root@wirenboard:~# cat /proc/interrupts | grep gpiolib # | root@wirenboard:~# cat /proc/interrupts | grep gpiolib # прерывание появилось в списке. 26 - внутренний номер прерывания, 0 - количество событий | ||
26: 0 gpio-mxs 3 gpiolib | 26: 0 gpio-mxs 3 gpiolib | ||
root@wirenboard:~# cat /proc/interrupts | grep gpiolib # | root@wirenboard:~# cat /proc/interrupts | grep gpiolib # после нескольких собтий, 76 - количество событий | ||
26: 76 gpio-mxs 3 gpiolib | 26: 76 gpio-mxs 3 gpiolib | ||
Строка 107: | Строка 107: | ||
Прерывания можно ловить из userspace с помощью системного вызова epoll() и select() на файл value. | |||
Пример работы см. [https://github.com/contactless/wiegand-linux-sysfs] | |||
См. также [http://elinux.org/GPIO elinux.org] | |||
=== | ===Прямое обращение через память процессора=== | ||
<b> | <b>Этот метод настоятельно НЕ РЕКОМЕНДУЕТСЯ для использования без достаточных оснований. Для работы из С/C++ стоит использовать работу через файлы в sysfs, как описано в предыдущем разделе</b>. | ||
Управлять GPIO можно с помощью прямого доступа к регистрам процессора, в обход Linux через интерфейс /dev/mem. При этом, по сравнению с работой через sysfs минимизуются наладные расходы. Этот метод можно использовать, | |||
если вам необходим очень быстрый доступ к GPIO, например bitbang протоколов или ШИМ. Стоит иметь в виду, что планировщик процессов всё ещё может вносить в работу программы значительные задержки. | |||
Рекомендуется выносить критичные ко времени задачи в ядро. | |||
См. [http://olimex.wordpress.com/2012/09/11/imx233-olinuxino-gpios-faster-and-faster/] , [https://github.com/OLIMEX/OLINUXINO/blob/master/SOFTWARE/iMX233/gpio-mmap.h] | |||
===GPIO | ===GPIO и Device Tree=== | ||
Указывать GPIO в Device Tree необходимо для настройки GPIO для работы в режиме программного SPI, I2C, для использования GPIO в качестве источника прерываний и т.д. | |||
Так например на пин 10@UEXT1 (CS) и пины 5@UEXT2 (SCL), 6@UEXT2 (SDA), 10@UEXT2 (CS) выведены линии GPIO процессора. Их можно сконфигурировать для использования например в качестве chip-select для SPI или в качестве I2C. | |||
GPIO процессора и периферийных устройств разбиты на банки (gpiochip). GPIO процессора разбиты на 3 банка по 32 GPIO: gpio0, gpio1, gpio2. Адресация GPIO в Device Tree происходит по номеру банка и номеру GPIO *внутри* банка. | |||
==== | ====Пример 1==== | ||
Определим сигнал 6@UEXT2 (SDA) в качестве источника прерываний для драйвера mrf24j40. Согласно таблице [[Special:MyLanguage/Список GPIO|Список GPIO]], сигнал соответствует GPIO 53 процессора. 53 принадлежит второму банку gpio (от 32 до 63). Номер GPIO внутри банка 53-32=21 : | |||
<pre> | <pre> |
Версия 12:46, 19 января 2016
В Wiren Board часть GPIO выведена на клеммники, часть выведена на разъёмы UEXT, часть используется для служебных целей. GPIO также используются для управления транзисторами для коммутации низковольтной нагрузки.
Соответствие между номерами GPIO в Linux и их местоположением и функцией можно найти в табличке WB SH 3.5: Список GPIO или WB rev. 2.8: Список GPIO.
В Wiren Board rev. 2.8 8 GPIO на специальном разъёме подключены через MCP23S08 и временно не работают со стандартным Linux API. Описание работы с ними есть на странице MCP23S08.
Все GPIO (как и остальные порты Wiren Board) работают с напряжением 3.3V. Ни в коем случае не подключайте к GPIO напрямую сигналы, напряжением больше 3.3V! В случае необходимости подключения устройств, работающих с более высоким напряжением, необходимо использовать схемы согласования или подключать (для 5V) через резистор в 20 кОм и более
На некоторых GPIO (в частности на 3х GPIO, выведенных на клеммники в Wiren Board rev. 2.8) можно программно установить 47к подтяжку к +3.3В. См. Pin_pull-up.
Интерфейс sysfs в Linux
GPIO в Linux поддерживаются через sysfs-интерфейс.
Для работы через sysfs c определённым GPIO его надо экспортировать:
Здесь и далее N - номер gpio
echo N > /sys/class/gpio/export
Экспортированные gpio появляются в каталоге /sys/class/gpio :
root@wirenboard:~# ls -1 /sys/class/gpio/ export gpio32 gpiochip0 gpiochip120 gpiochip32 gpiochip64 unexport
В директории /sys/class/gpioN теперь находятся файлы для работы с GPIO (где N - номер GPIO, как и было сказано ранее):
root@wirenboard:~# ls -1 /sys/class/gpio/gpioN/ active_low device direction edge power subsystem uevent value
Установка направления GPIO (ввод/вывод) производится с помощью записи в файл direction
echo in > /sys/class/gpio/gpioN/direction # установим GPIO номер N на ввод echo out > /sys/class/gpio/gpioN/direction # установим GPIO номер N на вывод
Чтение и установка значения GPIO производится с помощью файла value.
Чтение:
echo in > /sys/class/gpio/gpioN/direction # установим GPIO номер N на ввод cat /sys/class/gpio/gpioN/value # вернёт 1 или 0
Запись:
echo out > /sys/class/gpio/gpioN/direction # установим GPIO номер N на вывод echo 0 > /sys/class/gpio/gpioN/value # установим логический 0 (низкое напряжение) на GPIO номер N echo 1 > /sys/class/gpio/gpioN/value # установим логический 1 (высокое напряжение) на GPIO номер N
Интерфейс sysfs и прерывания
Через интерфейс sysfs можно запросить прерывания по изменению состояния процессора.
Установка прерывания производится путём записи значения в файл "edge". Значения могут быть:
- "none" - отключить прерывание
- "rising" - включить прерывание по нисходящему фронту
- "falling" - включить прерывание по восодящему фронту
- "both" - включить прерывание по обеим фронтам.
Пример:
root@wirenboard:~# echo 3 > /sys/class/gpio/export # экспортируем GPIO номер 3 (TB10 на WB3.3) root@wirenboard:~# cat /sys/class/gpio/gpio3/edge # проверяем состояние прерывания none root@wirenboard:~# echo falling > /sys/class/gpio/gpio3/edge # устанавливаем прерывание по нисходящему фронту root@wirenboard:~# cat /proc/interrupts | grep gpiolib # прерывание появилось в списке. 26 - внутренний номер прерывания, 0 - количество событий 26: 0 gpio-mxs 3 gpiolib root@wirenboard:~# cat /proc/interrupts | grep gpiolib # после нескольких собтий, 76 - количество событий 26: 76 gpio-mxs 3 gpiolib
Прерывания можно ловить из userspace с помощью системного вызова epoll() и select() на файл value. Пример работы см. [1]
См. также elinux.org
Прямое обращение через память процессора
Этот метод настоятельно НЕ РЕКОМЕНДУЕТСЯ для использования без достаточных оснований. Для работы из С/C++ стоит использовать работу через файлы в sysfs, как описано в предыдущем разделе.
Управлять GPIO можно с помощью прямого доступа к регистрам процессора, в обход Linux через интерфейс /dev/mem. При этом, по сравнению с работой через sysfs минимизуются наладные расходы. Этот метод можно использовать, если вам необходим очень быстрый доступ к GPIO, например bitbang протоколов или ШИМ. Стоит иметь в виду, что планировщик процессов всё ещё может вносить в работу программы значительные задержки. Рекомендуется выносить критичные ко времени задачи в ядро.
GPIO и Device Tree
Указывать GPIO в Device Tree необходимо для настройки GPIO для работы в режиме программного SPI, I2C, для использования GPIO в качестве источника прерываний и т.д. Так например на пин 10@UEXT1 (CS) и пины 5@UEXT2 (SCL), 6@UEXT2 (SDA), 10@UEXT2 (CS) выведены линии GPIO процессора. Их можно сконфигурировать для использования например в качестве chip-select для SPI или в качестве I2C.
GPIO процессора и периферийных устройств разбиты на банки (gpiochip). GPIO процессора разбиты на 3 банка по 32 GPIO: gpio0, gpio1, gpio2. Адресация GPIO в Device Tree происходит по номеру банка и номеру GPIO *внутри* банка.
Пример 1
Определим сигнал 6@UEXT2 (SDA) в качестве источника прерываний для драйвера mrf24j40. Согласно таблице Список GPIO, сигнал соответствует GPIO 53 процессора. 53 принадлежит второму банку gpio (от 32 до 63). Номер GPIO внутри банка 53-32=21 :
6lowpan@0 { compatible = "microchip,mrf24j40"; spi-max-frequency = <100000>; reg = <6>; interrupt-parent = <&gpio1>; interrupts = <21 0>; };