Что есть и не разрешено в подпрограмме обратного вызова (прерывания) для перехода состояния GPIO (perl, RPi :: WiringPi, Raspberry pi, Raspbian) - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь использовать контакты GPIO на Pi для сопряжения некоторых кнопок, на которые затем будет реагировать мое программное обеспечение. Это добавление некоторых элементов управления в существующее приложение Perl, поэтому моя новая работа также находится в Perl.

Действительно простой прототип аппаратной и программной работы; Я настраиваю вывод на режим ввода и подтягивания (и подключаю его так, чтобы кнопка заземляла вывод), и устанавливаю sh подпрограмму прерывания, и фактически, когда я нажимаю sh, вызывается подпрограмма прерывания. Так что я мог бы, по крайней мере, правильно установить различные пакеты и модули. (Наблюдается отскок контактов; в конечном итоге я справлюсь с этим в программном обеспечении.)

Однако, когда я пытаюсь поднять его до уровня, я сталкиваюсь со странными проблемами. Я перепробовал много вещей, которые потерпели неудачу по-разному. Здесь я ищу дополнительную информацию о том, что мне разрешено делать в функции прерывания (устанавливается $ pin-> set_interrupt ('main :: function_name')). Это называется «функцией прерывания», а также «обратным вызовом». Я сомневаюсь, что он действительно работает на уровне аппаратных прерываний (не думаю, что Linux даже поддерживает пользовательские обработчики прерываний!), Но, как правило, при такого рода обратных вызовах существуют жесткие правила или, по крайней мере, очень строгие рекомендации относительно того, что вы можете и можете сделать не делать там и что вы должны отложить на потом.

Но ни один из документов, которые я могу найти (конечно, не базовые c документы CPAN или perldo c на загруженных модулях), действительно не говорит мне много об ограничениях.

Для Например, я обнаружил, что вызовы регистраторов Log4 Perl работают рано в функции прерывания, но не поздно :-). Я подозреваю, что это плохая идея в функции прерывания, и одна вещь, которую я попробовал, оказалась удачной, но я могу ошибаться, и нет документации о том, что разрешено, а что нет.

Существует некоторое предположение, что функция прерывания может выполняться в другом потоке (но это из базовой библиотеки WiringPi, а не оболочки Perl, и я нашел ее в отношении функций, не упакованных оболочкой Perl, так что может и нет). Мое приложение не загружает библиотеку потоков (я избегаю ее; perl официально не одобряет потоки), но, возможно, что-то, что я использую в своем более сложном приложении (мое основное приложение, которое я собираюсь интегрировать) это использует MCE, который использует многопоточность или несколько разветвленных процессов, но мой прототип, с которым у меня возникли проблемы, проще и не работает).

Я также использую Class :: Tiny; Кажется, я могу вызывать методы класса в функции прерывания, но через некоторое время это становится странным. Я избегаю этого как можно больше в настоящее время.

Обычно, что вы хотите сделать, это в функции прерывания отметить, что произошло прерывание, а затем поставить в очередь событие для обработки в вашем главном событии l oop и сделать что-нибудь, возможно, чтобы разблокировать это l oop (как, скажем, сигнал condvar, которого ожидает l oop). Но не знаю, можно ли безопасно получить доступ к MCE :: Shared :: Condvar в функции прерывания.

Есть ли дополнительная информация о том, что разрешено и запрещено в функции прерывания? Существуют ли более сложные примеры кода (который не просто печатает что-то в функции прерывания)?

...