gpio: опросом или по прерыванию?
вот и я добрался до блога. поделиться маленькой программистской радостью :)
буквально на днях столкнулся с задачей — надо было быстро определить, подключена карта (ну или модуль) к прибору или нет. «быстро» значит без особых задержек между появлением/пропаданием карты и фактом обработки этого события.
для этих целей схемотехники завели GPIO pin на процессор. и первая реализация задачи была очень примитивной: опросом раз в 1 секунду читался файл /sys/class/gpio/gpio58/value. если в файле 1, то карта не подключена, а если 0 — подключена. инверсная логика, чтобы жизнь мёдом не казалась :)
да, совсем забыл сказать, что мы используем GPIO SYSFS. это такой интерфейс: из user-space виден файл, который можно писать и читать, а с другой — физическая ножка процессора. более подробно тут
а порадовало то, что pin, настроенный на вход, можно использовать как прерывание и при этом не залезать в kernel space! и вот как. в каталоге, соответствующем аппаратному GPIO (например /sys/class/gpio/gpio58/) лежит файл edge. этот файл позволяет настроить обработку прерывания: falling (по спаду сигнала), rising (по фронту), both (и по спаду, и по фронту). запись в этот файл none выключает обработчик.
я записал в этот файл «both», т.к. меня интересовало и подключение, и отключение.
дальше, используя системный вызов poll(), можно дождаться прерывания и прочитать значение из файла value.
то есть фактически реализуется блокирующее чтение.
механизм подробно описан в том же help’e
вполне рабочий пример кода есть тут
а я просто могу зафиксировать, что это действительно работает :)
да, нужно упомянуть, что у нас используется ядро 2.6.35-9
>инверсная логика, чтобы жизнь мёдом не казалась :)
а еще ядерщики-шалуны зачем-то организовали флажок active_low :D
кстати, да… :)
не то слово!
в дополнение к написанному в посте хочу сказать, что есть нюансы.
например, поскольку сигнал о присутствии карты появляется в результате механического контакта, мы столкнулись с дребезгом. то есть, на самом деле,
при втыкании карты может произойти не один перепад (0->1, 1->0).
и это надо учитывать.
аппаратно можно бороться одновибратором или rs-триггером, который сбрасывать после обработки прерывания..
или давить программно, запрещая работу (или прерывание) от конкретного gpio..
если отойти от режима работы с прерыванием и объявить пин, как gpio-button, то там д.б. встроенные средства по подавлению дребезга. кстати event при таком режиме легко ловится из юзерспейса..
не удивлюсь, если у PXA есть специализированные входы, типа «одиночной кнопки»..