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

5 комментариев

  1. jury093:

    >инверсная логика, чтобы жизнь мёдом не казалась :)
    а еще ядерщики-шалуны зачем-то организовали флажок active_low :D

  2. tony feldman:

    не то слово!

  3. Павел Курочкин:

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

    например, поскольку сигнал о присутствии карты появляется в результате механического контакта, мы столкнулись с дребезгом. то есть, на самом деле,
    при втыкании карты может произойти не один перепад (0->1, 1->0).

    и это надо учитывать.

    • jury093:

      аппаратно можно бороться одновибратором или rs-триггером, который сбрасывать после обработки прерывания..
      или давить программно, запрещая работу (или прерывание) от конкретного gpio..
      если отойти от режима работы с прерыванием и объявить пин, как gpio-button, то там д.б. встроенные средства по подавлению дребезга. кстати event при таком режиме легко ловится из юзерспейса..
      не удивлюсь, если у PXA есть специализированные входы, типа «одиночной кнопки»..