Библиотека журналирования ESP-IDF замедляет обработку ISR
Я взламываю проект с помощью модуля ESP32-WROOM. Я использую несколько таймеров с сигналами тревоги, а также некоторые периферийные устройства, запускающие ISR. В процедуре ISR я отправляю события в очередь и получаю их в задаче. Обычно я наблюдаю задержку в ~50 микрон между процедурой ISR и задачей.
Я добавил компонент esp_log
для регистрации в UART. Если я вызываю некоторый ESP_LOGx
в задаче после получения события очереди, вышеупомянутая задержка в некоторых случаях вырастает до 25 миллис (в зависимости от объема журналирования).
В чем причина? Имеет ли esp_log
длинные внутренние разделы noInterrupt
? Есть ли способ их избежать? Какие еще средства правовой защиты?
Эти задержки очень неприятны, потому что, с одной стороны, мне нужно ведение журнала, чтобы все заработало. С другой стороны, эти задержки переворачивают все тайминги с ног на голову...
На самом деле я переключился на esp_log
в форме ручного регистратора. В моем регистраторе у меня была очередь Fifo размером 5 тыс. для данных журнала. Вызовы журналирования форматируют строки и помещают их в очередь. Задача с низким приоритетом извлекает данные и печатает их в UART. Это было намного лучше с точки зрения производительности. Я переключился на esp_log
для более широкой функциональности, но... Возвращаюсь назад, если не будет исправления.
@ak., 👍0
1 ответ
Лучший ответ:
Поскольку ваш регистратор использует UART, вам необходимо учитывать время передачи.
Предполагаем, что вы используете линию передачи данных со скоростью 9600 бод и отправляете около 25 байт.
Один байт содержит 10 бит в проводе, стартовый бит, биты данных и как минимум один стоповый бит. В протоколе есть и другие варианты, но в основном это все.
Каждый бит занимает 1/9600 секунды, это определение скорости 9600 бод. (На самом деле это упрощенно, но тем не менее здесь правильное число.) 10 бит одного байта занимают t_Byte = 10/9600 с = 1,042 мс.
Чтобы отправить 25 байтов, это в сумме составит около 25 мс.
Извлеченный урок: не выполняйте вход напрямую в UART при выполнении задач, критичных по времени. Вы нашли общее решение, поставив байты в очередь для отправки. Просто убедитесь, что очередь не будет заполняться в долгосрочной перспективе.
- Чтение квадратурного энкодера в реальном времени с полным разрешением только с одним прерыванием на ATmega328
- Как использовать ESP_LOGx?
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
- ESP32 - "Детектор Браунаута был активирован" при запуске Wi-Fi
это имеет смысл, я понял, что могу переопределить функцию vprintf
esp_log_set_vprintf
и реализовать буферизацию и асинхронную очистку буфера, @ak.