По крайней мере, вы делаете way слишком много в вашем обработчике прерываний (gpio_isr_handler()
).
Обработчики прерываний interrupt поток любого кодав настоящее время работает.Они могут произойти в любое время, между инструкциями в подпрограмме.Если код не принимает меры предосторожности, чтобы гарантировать, что его структуры данных находятся в согласованном состоянии, вы требуете повреждения данных и сбоев.Для этого необходимо заблокировать прерывания в «критических секциях», что является очень дорогой операцией и может привести к пропущенным прерываниям.Так что системные подпрограммы будут делать это очень редко.
Вы также хотите, чтобы обработчики прерываний были краткими, потому что они блокируют все другие действия в системе - поэтому сетевой стек и другие служебные функции не могут выполняться, пока вы ещев обработчике прерываний.
Вы абсолютно не должны вызывать vTaskDelay()
из обработчика прерываний.Что это хотя бы значит?В лучшем случае это повлияет на любую задачу, которая была прервана, что, если выполняется несколько задач, будет случайной задачей.
Вам также не следует вызывать какие-либо функции stdio из обработчика прерываний.Опять же, вы можете прервать другую функцию stdio;его структуры данных могут быть в несовместимом состоянии, и если он использует последовательный порт, возможно, что аппаратное обеспечение также может быть в несовместимом состоянии.
Правильный способ сделать это - просто запустить программу обработки прерываний.задача.Поместите ваш текущий код из gpio_isr_handler()
в задачу в бесконечном цикле с помощью a, запустите задачу в app_main()
и пусть gpio_isr_handler()
просто разбудит задачу.Используйте vTaskSuspend()
в начале цикла, чтобы задача дожидалась его пробуждения.
Вы можете безопасно вызывать задачу из обработчика прерываний с одним из:
Начать с xTaskResumeFromISR()
, это самый простой способ вывести задачу из обработчика прерываний.
Конструктивно вы также должны переместить цикл while()
из app_main()
в его собственную задачу, которая является задачей, которую ваш код выполняетжил в gpio_isr_handler()
должен возобновиться.