Gpio-event
Содержание |
Вступление
Некоторые GPIO процессора имеют возможность генерировать прерывание при изменении уровня сигнала.
На данный момент прерывания доступны на восьми пинах, GPIO0 - GPIO7. Но прерывание на GPIO0 используется для нужд системы, так что для пользовательской обработки доступны семь оставшихся пинов.
Отступление
У процессоров DM36x есть встроенный контроллер Ethernet (EMAC - Ethernet Media Access Control), но он сделан таким образом, что при его активности становятся недоступны сразу все прерывания GPIO. Только по этой причине пришлось отказаться от родного скоростного Ethernet и сделать сеть на отдельном чипе.
Возможно, сделаем шилд для поддержки родного Ethernet.
Типы сигналов
Прерывания на пинах GPIO генерируются двух типов
Тип | Описание |
---|---|
Rising | Изменение уровня с LOW на HIGH |
Falling | Изменение уровня с HIGH на LOW |
Например, если на пине GPIO было нулевое напряжение (уровень LOW), а затем мы подали на него 3.3В (уровень HIGH) - будет сгенерировано прерывание с типом Rising.
Драйвер user-space
Для обработки прерываний на пинах GPIO в user-space, т.е. в пользовательских приложениях, требуется драйвер.
Драйвер называется gpio-event, позаимствован у Gumstix.
По умолчанию, в прошивке драйвер gpio-event собран в составе ядра, так что пересборка не требуется.
Но если вдруг понадобится - он находится в
CONFIG_V2R_GPIOEVENT: Virt2real GPIO event driver. Taken from Gumstix. Symbol: V2R_GPIOEVENT [=y] Type : tristate Prompt: GPIO event driver Defined at drivers/v2r/Kconfig:35 Depends on: V2R_DRIVERS [=y] Location: -> Device Drivers -> Virt2real device drivers (V2R_DRIVERS [=y])
Этот драйвер непосредственно обрабатывает прерывания (это возможно только в ядре) и позволяет получить информацию о прерывании пользовательским приложениям путём чтения файла драйвера.
Управление драйвером
Управление производится с помощью вспомогательной утилиты "gpio-event". Она включена в состав файловой системы, но в случае необходимости можно установить вручную.
opkg-cl update opkg-cl install gpio-event
Добавление пинов
Необходимо выполнить команду gpio-event с параметрами
gpio-event <gpio_num>:<int_type>:<debounce> ...
Параметр | Возможные значения | Описание |
---|---|---|
gpio_num | 1-7 | Номер GPIO (именно GPIO, не CON!) |
int_type | r,f,b | Тип прерывания. r - Rising, f - Falling, b - Both (и Rising, и Falling) |
debounce | 0-255 | время (в миллисекундах) для устранения дребезга контактов |
Например, чтобы установить наблюдение за любыми изменениями уровней на пинах GPIO1-3, с устранением небольшого дребезга, мы должны выполнить команду
gpio-event 1:b:20 2:b:20 3:b:20
Также необходимо перевести пины в режим Input, иначе прерывания не будут работать.
echo "set gpio 1 input 0" > /dev/v2r_gpio echo "set gpio 2 input 0" > /dev/v2r_gpio echo "set gpio 3 input 0" > /dev/v2r_gpio
Удаление пинов
Аналогично добавлению пинов, только номер gpio_num надо указать с минусом.
т.е.
gpio-event -<gpio_num>
Чтение текущих настроек
Чтобы узнать, какие пины настроены в данный момент, можно прочитать файл
# cat /proc/gpio-event/pins GPIO: 1 Edge: Both Debounce: 20 msec GPIO: 2 Edge: Both Debounce: 20 msec GPIO: 3 Edge: Both Debounce: 20 msec
Получение информации о поступивших прерываниях
В текстовом виде
Чтением файла драйвера
cat /dev/gpio-event 3 R 1395111091.841438 3 F 1395111091.907008 3 R 1395111091.962030
3 - номер GPIO
R/F - тип изменения уровня (Rising или Falling)
1395111091.962030 - таймстамп поступления прерывания в формате "секунды.миллисекунды"
Или, аналогично, через утилиту gpio-event
gpio-event --execute echo
или
gpio-event --monitor
В бинарном виде
Только из пользовательского приложения.
См. пример https://github.com/virt2real/othersoft/blob/master/gpio-event/usrange.c
Заключение
Таким образом, измерение разницы в таймстампах изменения уровней позволяет узнать длительность требуемого сигнала на пине GPIO и получить аналог ардуинской фунции pulseIn(); что позволяет реализовать обработку сигнала, например, с ультразвукового дальномера - Дальномер.