- Электрические характеристики GPIO
- Количество GPIO, мультиплексирование
- Конфигурирование мультиплексированных выводов в качестве GPIO
- Важные замечания и особенности GPIO
- Управление GPIO через sysfs, инструмент gpioctl
- Инструмент Fast-GPIO
Как и любой другой микроконтроллер, MT7688 (на котором собран модуль Omega2) имеет некоторое количество линий GPIO. GPIO — это такие выводы, каждым из которых пользователь может управлять непосредственно, в отдельности от всех остальных выводов. Их можно настраивать «на вход», — чтобы считывать с вывода логический уровень напряжения установленный внешней схемой, или «на выход» — чтобы контроллер мог сам устанавливать на соответствующем выводе логический уровень напряжения, подключая этот вывод к своей нулевой или питающей шине.
В этой статье будет подробно описано как настраивать выводы GPIO в модулях Omega2, как ими управлять, какие команды и инструменты для этого используются, но для начала давайте рассмотрим электрические характеристики выводов GPIO.
Электрические характеристики GPIO
Parameter | Минимум (В) | Максимум (В) |
Input HIGH | 2.0 | 3.6 |
Input LOW | -0.3 | 0.8 |
Output HIGH | 2.4 | 3.3 |
Output LOW | -/- | 0.4 |
Как видите, Omega2 использует логику с уровнями напряжения 3,3 Вольта. Стандартные устройства 5-вольтовой логики обычно воспринимают входной сигнал 3.3В как HIGH, однако их выходной сигнал HIGH соответствует уровню 4.4-5В. Это означает, что выходы модулей Omega2 можно подключать напрямую ко входам устройств 5-Вольтовой логики, однако попытка подключить выходы устройств 5-Вольтовой логики ко входам модулей Omega2 приведет к повреждению последних. Вот здесь можно почитать про устройства сопряжения различных логических уровней.
Количество GPIO, мультиплексирование
Теперь давайте посчитаем, а сколько же всего выводов GPIO нам доступно в модулях Omega2. Здесь нужно учесть следующее:
- во-первых, на внешние выводы модулей Omega выводятся не все ноги контроллеров MT7688 (у него аж 156 ног). Количество выведенных наружу ног контроллера зависит от версии модуля (Omega2 или Omega2S).
- во-вторых, у контроллеров MT7688 (как и у большинства остальных контроллеров) существуют выводы, которые мультиплексированы с какими-либо другими функциями помимо GPIO. Такие выводы, в зависимости от настроек, могут использоваться для работы не в качестве GPIO, а в качестве чего-то другого (UART, I2C, SPI и тому подобное).
- ну и в-третьих, на официальной картинке GPIO подписаны не совсем правильно (не все подписанные как GPIO ноги могут использоваться в качестве таковых и не все ноги помеченные только как GPIO ни с чем не мультиплексированы).
Поскольку модулей Omega2S у меня нет, далее я буду рассказывать только о модулях Omega2. Ниже приведена исправленная картинка с распиновкой:
Видно, что в этом модуле в качестве GPIO может использоваться 17 ног (GPIO 0,1,2,3,4,5,6,11,12,13,15,16,17,18,19,45,46), при этом всего одна нога не используется более ни для чего (GPIO11), а остальные 16 ног могут быть помимо GPIO сконфигурированы для других задач.
Конфигурирование мультиплексированных выводов
Для конфигурирования мультиплексированных выводов можно использовать инструмент omega2-ctrl.
Чтобы узнать как пользоваться этим инструментом — просто наберите в командной строке omega2-ctrl ? и нажмите Enter (так можно получить подсказку практически по всем командам):
root@Omega-XXXX:/# omega2-ctrl ? Usage: omega2-ctrl gpiomux get Functionality: List the current GPIO muxing configuration Usage: omega2-ctrl gpiomux set <gpio group=""> <mux setting=""> Functionality: Set the gpio muxing for the specified GPIO signal Usage: omega2-ctrl refclk get Functionality: Display the current refclk setting Usage: omega2-ctrl refclk set <frequency (mhz)=""> Functionality: Set the refclk to the specified frequency if possible</frequency></mux></gpio> |
Итак, получить текущую конфигурацию мультиплексированных выводов Omega2 можно с помощью команды:
omega2-ctrl gpiomux get |
В результате её выполнения вы получите ответ следующего вида:
root@Omega-XXXX:/# omega2-ctrl gpiomux get Group i2c - [i2c] gpio Group uart0 - [uart] gpio Group uart1 - [uart] gpio Group uart2 - [uart] gpio pwm Group pwm0 - [pwm] gpio Group pwm1 - [pwm] gpio Group refclk - refclk [gpio] Group spi_s - spi_s [gpio] Group spi_cs1 - [spi_cs1] gpio refclk Group i2s - i2s [gpio] pcm Group ephy - [ephy] gpio Group wled - wled [gpio] |
Текущая конфигурация для каждой группы выводов отмечена квадратными скобками — []. Если посмотреть на приведенный выше пример, то можно сказать, что для группы uart1 доступны режимы uart и gpio, при этом в текущий момент выбран режим uart.
Для переключения конкретной группы выводов в определённый режим используется следующая команда:
omega2-ctrl gpiomux set <hardware pin="" group=""> <mode> </mode></hardware> |
Например, приведённая ниже команда настраивает группу выводов UART1 для работы в режиме GPIO:
omega2-ctrl gpiomux set uart1 gpio |
Если проверить результат работы этой команды с помощью команды gpiomux get, то мы увидим следующее:
root@Omega-XXXX:/# omega2-ctrl gpiomux get Group i2c - [i2c] gpio Group uart0 - [uart] gpio Group uart1 - uart [gpio] Group uart2 - [uart] gpio pwm Group pwm0 - [pwm] gpio Group pwm1 - [pwm] gpio Group refclk - refclk [gpio] Group spi_s - spi_s [gpio] Group spi_cs1 - [spi_cs1] gpio refclk Group i2s - i2s [gpio] pcm Group ephy - [ephy] gpio Group wled - wled [gpio] |
То есть текущая конфигурация выводов Group uart1 изменилась с uart на gpio.
Обратите внимание, что в выдаваемом командой gpiomux get списке групп выводов, вообще-то говоря не все группы выведены на разъёмы модуля Omega2. Группы uart2 (GPIO20, GPIO21), refclk (GPIO37), ephy и wled (GPIO44) на внешние разъёмы модулей Omega2 не выводятся, они актуальны только для модулей Omega2S. Хотя выводом wled поиграться всё же можно, к нему подключен расположенный на плате модуля светодиод.
Важные замечания и особенности GPIO
Существует ряд важных замечаний относительно использования GPIO, а именно:
Некоторые выводы сопряжены с загрузкой модуля и по этой причине должны во время загрузки оставаться свободными, то есть не должны оказаться подтяутыми к земле или питанию. Список таких ног приведён ниже:
GPIO | Description |
GPIO1 | I2S SDO |
GPIO6 | SPI CS1 |
GPIO7 | SPI CLK |
GPIO8 | SPI MOSI |
GPIO12 | UART TX0 |
GPIO45 | UART TX1 |
Расположенная на плате модуля Omega2 флэш-память подключена к контроллеру с помощью интерфейса SPI. При этом в качестве сигнала Chip Select она использует сигнал с вывода Chip Select 0. Поскольку у контроллера есть два сигнала Chip Select для шины SPI, то к модулю Omega2 можно подключить дополнительное устройство SPI, которое будет использовать сигнал Chip Select 1.
Выводы SPI — CLK, MOSI и MISO — выводятся на контакты модуля Omega2 и вообще-то могут быть специальными средствами (но не через omega2-ctrl) настроены как GPIO 7,8 и 9. Однако делать этого категорически не следует, поскольку это может привести (и обязательно приведёт) к проблемам с флэш-памятью.
Управление GPIO через sysfs, инструмент gpioctl
Во все linux-системы встроена виртуальная файловая система sysfs, предоставляющая пользователю интерфейс к структурам ядра. Информация обо всех устройствах, модулях и компонентах ядра представлена в этой псевдофайловой системе в виде файлов. Неожиданно, да? На самом деле это конечно не настоящие файлы в привычном понимании (поэтому далее я буду брать их в кавычки). Но суть не в этом. Суть в том, что читая/записывая эти «файлы», мы можем управлять соответствующими компонентами, в том числе и GPIO.
«Файлы» необходимые для управления GPIO содержатся в директории /sys/class/gpio. В первую очередь нас интересуют «файлы» export и unexport. Они доступны только для записи и используются чтобы запросить у ядра linux доступ к управлению через sysfs каким-либо выводом GPIO или отменить такую возможность.
Для получения доступа к управлению выводом GPIO — нужно записать в «файл» export номер этого GPIO. Из командной строки это может выглядеть так (например, для GPIO19):
echo 19 > export |
В случае, если всё пройдёт успешно, в папке /sys/class/gpio появится папка gpioN (N — номер вывода, то есть в нашем примере это будет папка GPIO19), содержащая доступные для чтения/записи «файлы» для работы с запрошенным выводом : direction, value, edge, active_low.
Файл «direction» используется чтобы задать или определить направление работы вывода. Если мы хотим сконфигурировать вывод для работы в качестве входа (например, чтобы определять состояние подключенной к выводу кнопки) — в этот файл нужно записать значение in. Для конфигурирования вывода на работу в качестве выхода (например, чтобы включать/выключать подключенный к выводу светодиод) — нужно записать в этот файл значение out. По умолчанию, при переключении вывода на выход, на нём установится значение low. Для обеспечения безаварийной работы в файл «direction» могут быть вместо out записаны значения low или high, что приведёт к конфигурированию вывода на выход с соответствующим начальным значением. Узнать текущее направление работы вывода можно прочитав содержимое файла direction.
Файл «value» используется чтобы считать состояние вывода или переключить вывод в состояние 0 (low) или 1 (high). Считывание доступно при любой конфигурации направления работы вывода, а установка актуальна только для выводов сконфигурированных на выход. При установке состояния любое записываемое в файл «value» значение отличное от нуля будет трактоваться как high.
Файл «edge» используется для настройки прерываний от изменения состояния вывода, а файл «active_low» — для настройки соответствия значений low и high высокому и низкому уровням сигнала на выводе (можно сделать так, чтобы высокий уровень напряжения считался нулём, а низкий — единицей). Более подробно мы на sysfs останавливаться не будем, иначе статья получится слишком большой. Теперь вы по крайней мере знаете в каком направлении копать, а мы идём дальше.
В модулях Omega2 для нашего удобства (ну по крайней мере так объявлено) сделан специальный инструмент командной строки gpioctl, работающий как раз на основе описанного выше механизма sysfs. Ну то есть, мы с его помощью можем писать команды не напрямую системе sysfs, а этому инструменту, а уже он за нас будет обращаться в sysfs.
В чём тут удобство и почему мы не можем работать напрямую через sysfs? Хм… ну, видимо удобство в синтаксисе. Так или иначе, инструмент есть и я про него напишу.
Синтаксис командной строки gpioctl показан ниже:
gpioctl <option> <gpio number=""></gpio></option> |
Всего для этого инструмента доступны 7 опций: dirin, dirout, dirout-low, dirout-high, get, set, clear. Ниже описано назначение и примеры использования каждой из этих опций.
Опция dirin позволяет задать направление работы вывода на вход. Пример (конфигурирование GPIO19 на вход):
root@Omega-XXXX:/# gpioctl dirin 19 Using gpio pin 19. |
Опция dirout позволяет задать направление работы вывода на выход. Пример (конфигурирование GPIO19 на выход):
root@Omega-XXXX:/# gpioctl dirout 19 Using gpio pin 19. |
Опция dirout-low позволяет задать направление работы вывода на выход с начальным значением low на выходе. Пример (конфигурирование GPIO19 на выход с начальным значением low):
root@Omega-XXXX:/# gpioctl dirout-low 19 Using gpio pin 19. |
Опция dirout-high позволяет задать направление работы вывода на выход с начальным значением high на выходе. Пример (конфигурирование GPIO19 на выход с начальным значением high):
root@Omega-XXXX:/# gpioctl dirout-high 19 Using gpio pin 19. |
Опция get позволяет позволяет прочитать текущий логический уровень на соответствующем выводе. Пример (чтение логического уровня на выводе GPIO19):
root@Omega-XXXX:/# gpioctl get 19 Using gpio pin 19. Pin 19 is LOW |
Опция set позволяет позволяет установить логический уровень 1 (high) на соответствующем выводе, если он настроен на выход. Пример (установка логического уровня 1 на выводе GPIO19):
root@Omega-XXXX:/# gpioctl set 19 Using gpio pin 19. |
Опция clear позволяет позволяет установить логический уровень 0 (low) на соответствующем выводе, если он настроен на выход. Пример (установка логического уровня 0 на выводе GPIO19):
root@Omega-XXXX:/# gpioctl clear 19 Using gpio pin 19. |
Хотелось бы отметить, что для мультиплексированных выводов все переключения gpio с помощью sysfs (как и с помощью основанного на sysfs инструмента gpioctl) будут выполняться только в случае, если соответствующий вывод сконфигурирован в качестве gpio. В противном случае переключения реально выполняться не будут, хотя считывание значений из файла value или командой get будет показывать, что переключение вроде бы выполнено и уровень установился такой, как мы хотели. Видимо это связано с тем, из какого реального регистра контроллера читаются данные при подобной проверке состояния. Обычно у контроллера существуют регистры PINx, из которых можно считать реальное состояние выводов и PORTx, из которых можно прочитать состояние, которое установится при конфигурировании выводов на выход. Ну и, судя по всему, через файл value и команду gpioctl get считываются данные из регистра PORTx, а не из регистра PINx.
Кроме того, хотелось бы отметить отсутствие у инструмента gpioctl отдельной опции для определения направления работы вывода, хотя sysfs позволяет это сделать (нужно просто прочитать значение из файла direction). То ли не доделали, то ли… В общем, нет такой опции.
Команда fast-gpio подобна команде gpioctl в том смысле, что она также используется для управления GPIO. Различия заключаются в том, что gpioctl работает через sysfs, а fast-gpio работает непосредственно с регистрами GPIO контроллера и является более быстрой.
Использование команды:
Для получения списка вариантов использования команды, просто выполните fast-gpio из командной строки:
root@Omega-XXXX:/# fast-gpio Usage: fast-gpio set-input <gpio> fast-gpio set-output <gpio> fast-gpio get-direction <gpio> fast-gpio read <gpio> fast-gpio set <gpio> <value: 0="" or="" 1=""> fast-gpio pwm <gpio> <freq in="" hz=""> <duty cycle="" percentage=""></duty></freq></gpio></value:></gpio></gpio></gpio></gpio></gpio> |
С помощью опций set-input, set-output можно сконфигурировать направление работы выводов GPIO. Примеры:
fast-gpio set-input 19 > Set direction GPIO19: input |
fast-gpio set-output 19 > Set direction GPIO19: output |
Опция get-direction позволяет определить направление работы выводов GPIO. Пример:
fast-gpio get-direction 19 > Get direction GPIO19: output |
Опция read позволяет прочитать состояние вывода, то есть установленный на нём логический уровень (независимо от сконфигурированного направления работы). Пример:
root@Omega-XXXX:/# fast-gpio read 19 > Read GPIO19: 0 |
Опция set позволяет установить на выбранном выводе необходимое значение. Примеры:
fast-gpio set 19 0 > Set GPIO19: 0 |
fast-gpio set 19 1 > Set GPIO19: 1 |
Если вывод не настроен на выход, то fast-gpio принудительно изменит его направление на выход перед установкой значения.
Опция pwm предназначена для организации программного ШИМ на выбранном выводе. В качестве дополнительных параметров с этой опцией задаются:
fast-gpio pwm 19 1000 50 |
Команда с опцией pwm запускает фоновый процесс, который генерирует ШИМ-сигнал, переключая выход GPIO через определённые заданные промежутки времени. Этот метод потенциально неточен, поскольку CPU может быть прерван другим процессом или задачей. Программного ШИМа может быть достаточно для диммирования LED, но недостаточно для операций, требующих большой точности, таких как управление сервоприводом.
Чтобы остановить ШИМ нужно выполнить для этого же вывода команду fast-gpio с любой другой опцией вместо pwm или переключить вывод на вход командой gpioctl.
Кстати, в нашем магазине можно купить микрокомпьютер Omega2 по очень привлекательной цене.
- Часть 1. Первое знакомство
- Часть 2. Использование GPIO
- Часть 3. Док-плата
- Часть 4. Работа с файлами
- Часть 5. Работа с USB flash-дисками
- Часть 6. Установка, настройка и использование php для интерактивного взаимодействия
- Часть 7. Выполнение задач по расписанию с помощью планировщика Cron
- Часть 8. Подключаем проводной Ethernet.
- Часть 9. Сборка альтернативной прошивки на базе OpenWRT.