ESP8266:Прошивки/Arduino/FAQ/Есть код, при запуске которого ESP8266 крашится. Как решить эту проблему?

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



Есть код, при запуске которого ESP8266 крашится. Как решить эту проблему?[1]

ESP постоянно перезапускается. Вы не знаете почему и не знаете, что с этим делать.

Оставить панику.

В большинстве случаев ESP, крашась, дает достаточно подсказок в мониторе порта – с их помощью можно определить, что именно стало причиной проблемы.

Что говорит ESP

Начинаем с открытия монитора порта ( Ctrl + ⇧ Shift + M ), чтобы взглянуть на данные, сообщаемые ESP. Типичный краш выглядит примерно так:

Типичные логи, появляющиеся при краше

Перед тем, как копипастить логи в Google, попробуйте определить основные особенности этих перезапусков:

  • ESP перезапускается случайно или при определенных условиях (вроде обслуживания веб-страницы)?
  • Вы всегда видите одинаковые код исключения и трассировку стека или они меняются?
  • Эта ошибка возникает при запуске стандартных, не редактированных скетчей-примеров (вроде тех, что можно найти, кликнув в IDE Arduino по Файл > Примеры)?

Если перезапуски возникают случайно, а код исключения каждый раз разный, то проблема, возможно, в ПО. Если проблема возникает при использовании стандартных скетчей и стабильной версии аддона, то это почти наверняка аппаратная проблема.

Приводим в порядок оборудование

Если вы подозреваете, что это аппаратная проблема, то сначала нужно привести в порядок оборудование. Нет никакого смысла в диагностике ПО, пока ваша плата случайно крашится из-за недостаточного питания, недостающих бутстрепных резисторов или неподключенных контактов.

Если вы используете стандартный («голый») модуль ESP8266, обязательно уделите время подключению бустрепных резисторов и настройке питания (в оригинале здесь есть ссылка на статью с рекомендациями, но битая – прим. пер.).

Если используете плату/модуль с интегрированными питанием и USB-Serial конвертером, то в этом случае, как правило, достаточно подключиться к USB-хабу, выдающему стандартные 0,5А, которые не приходиться делить с другими USB-девайсами.

В любом случае стоит проверить, что ваш модуль корректно запускает стандартные скетчи-примеры для установления соединения (вроде «HelloServer.ino»).

Что является причиной перезапусков?

Итак, вы удостоверились, что ESP8266 не гложет никакая аппаратная проблема. Но он по-прежнему перезапускается. Таким образом ESP8266 реагирует на аномальное поведение программы. Если что-то не так, он перезапускается, чтобы сообщить вам об этом.

Вот два типичных сценария, которые заставляют ESP8266 перезапускаться:

  • Исключения – когда код выполняет запрещенную операцию (вроде попытки записать данные на несуществующий участок памяти)
  • Сторожевой таймер – когда код зависает, слишком долго гоняя по циклу или выполняя определенное задание, из-за чего не удается выполнить важные процессы вроде коммуникации по WiFi

О том, как определить, какой именно сценарий случился у вас, читайте ниже.

Исключения

Типичный перезапуск, вызванный исключением, выглядит примерно так:

Расшифровка кода исключения

Начните с поиска нужного кода в таблице «Причины исключений», чтобы понять, какая именно проблема вызывает перезапуск ESP8266. Если у вас нет ни одной подсказки, что это и где происходит, воспользуйтесь плагином EspExceptionDecoder для IDE Arduino, чтобы определить строчку кода, на которой происходит перезапуск. Подробнее о том, как это сделать, читайте ниже, в разделе «Определение строчки, в которой крашится код».

Сторожевой таймер

ESP8266 оснащен двумя сторожевыми таймерами (или «wdt», что является сокращением от «watchdog timer»), которые наблюдают за скетчем, чтобы определить, не завис ли он.

  • Программный сторожевой таймер – включен в SDK, который является частью аддона esp8266/Arduino, загружаемого на модуль вместе со скетчем
  • Аппаратный сторожевой таймер – встроен в ESP8266 и действует, если программный таймер слишком долго отключен, не работает или его нет вовсе.

Как определить тип сторожевого таймера, вызвавшего перезапуск? Эта информация есть в логах, которые выводятся в монитор порта после перезапуска ESP8266.

Ниже показан пример краша, вызванного программным сторожевым таймером:

Пример перезапуска, вызванного программным сторожевым таймером

Перезапуск, вызванный программным таймером, определить проще, поскольку в этом случае в логах также присутствует трассировка стека. Ее можно использовать для обнаружения строчки, которая вызвала перезапуск.

Ниже показан перезапуск, вызванный аппаратным сторожевым таймером:

Пример перезапуска, вызванного программным сторожевым таймером

Аппаратный сторожевой таймер – это последний рубеж, на котором ESP может сообщить вам, что программа зависла (если программный таймер отключен или не работает).

Обратите внимание, что при перезапуске, вызванном аппаратным таймером, трассировка кода не сообщается, поэтому для того, чтобы определить место зависания, нужно будет воспользоваться отладочными сообщениями. Для этого расставьте в разных строчках скетча несколько функций Serial.print(). Затем, запустив скетч и понаблюдав за тем, какие отладочные сообщения появляются в мониторе порта перед перезапуском, определите, какая именно строчка его запускает. Если в используемом скетче или библиотеке есть опция отладки – включите ее. Это тоже должно помочь в решении проблемы.

Определение строчки, в которой крашится код

Благодаря плагину EspExceptionDecoder, разработанному пользователем @me-no-dev, в расшифровке трассировки стека теперь нет ничего сложного. О том, как установить его в IDE Arduino, читайте тут.

Если у вас нет проблемного кода, воспользуйтесь скетчем ниже:

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("Let's provoke the s/w wdt firing...");
             //  "Давайте-ка сделаем перезапуск,
             //   вызванный программным сторожевым таймером..."
  //
  // ждем, пока скетч войдет в бесконечный цикл
  //
  while(true);
  //
  Serial.println("This line will not ever print out");
             //  "Эта строчка никогда не будет напечатана"

}

void loop(){}

Загрузите его на ESP8266 ( Ctrl + U ) и запустите монитор порта ( Ctrl + ⇧ Shift + M ). Вскоре после этого ESP8266 начнет перезапускаться каждые несколько секунд, и с каждым рестартом в мониторе порта будет появляться сообщение «Soft WDT reset» и трассировка стека. Уберите в мониторе порта галочку рядом с пунктом «Автопрокрутка», чтобы остановить прокрутку сообщений. Скопируйте трассировку стека и кликните в IDE Arduino на Инструменты > ESP Exception Decoder (ESP Exception Decoder > Tools).

Расшифровка трассировки стека, шаги 1 и 2

Теперь вставляем скопированную трассировку стека в окно Esp Exception Decoder.

В нижней части этого окна должен появиться список расшифрованных строчек скетча, который вы только что загрузили на ESP8266. В верхней части списка (как и в верхней части трассировки стека) есть отсылка к последней выполненной строчке кода – той, что была обработана прямо перед срабатыванием программного сторожевого таймера, активировавшего перезапуск ESP8266. Это должна быть строка номер «5» – найдите ее в скетче. Она содержит Serial.println("Let's provoke the s/w wdt firing...") и стоит прямо перед циклом while(true), из-за которого сработал сторожевой таймер (на комментарии можете не обращать внимание, компилятор их проигнорирует).

Расшифровка трассировки стека, шаги с 3 по 6

Итак, вооруженный расшифровщиком Esp Exception Decoder, вы можете определить, на какой именно строке кода крашнулся модуль, имея в распоряжении лишь трассировку стека. Та же процедура применима к крашам, причиной которых являются исключения.

Примечание: Расшифровщик ESP Exception Code способен расшифровывать строчки только тех скетчей, что были загружены на модуль. Кроме того, ESP Exception Code не сможет корректно расшифровать трассировку стека, сгенерированную скетчем, который был скомпилирован и загружен не IDE Arduino, а какой-то другой программой.

Если зашли в тупик, пишите баг-репорт

Как правило, рекомендации выше позволяют решить все проблемы с написанным вами кодом. Но, возможно, что ESP8266 крашится внутри библиотеки или кода, с которым вы знакомы плохо и потому не можете решить проблему самостоятельно. Если это ваш случай, тогда имеет смысл написать автору кода баг-репорт (т.е. отчет об ошибке).

Если в репозитории автора кода есть инструкции по написанию баг-репортов, следуйте им. Если таких инструкций нет, советуем указать в вашем баг-репорте следующее:

  • Пошаговую инструкцию для действий, которые приводят к появлению бага
  • Подробную информацию об используемом вами оборудовании
  • Если баг возникает на стандартной ESP-плате, которая оснащена цепью питания и USB-интерфейсом, которую можно купить в магазинах и к которой не подключено никакого дополнительного оборудования, укажите просто тип платы или ссылку на ее описание
  • Настройки IDE Arduino, используемые для загрузки скетча
  • Лог с ошибками и сообщениями, которые сгенерировал скетч (чтобы логи были более подробными, включите функцию отладки)
  • Расшифрованную трассировку стека
  • Копию загруженного скетча
  • Копию всех библиотек, использованных в скетче
  • Если вы используете стандартные библиотеки из Менеджера библиотек, то просто укажите версии этих библиотек
  • Версию аддона ESP8266 для IDE Arduino
  • Название и версию ваших IDE и ОС

Как видите, с таким разнообразием модулей ESP8266, библиотек, версий библиотек, версий аддона ESP8266 для IDE Arduino, типов и версий ОС, предоставляемая вами информация должна быть максимально подробной. Лишь видя такие подробные данные, люди захотят сопоставить ваши настройки, ПО и оборудование со своими. Если вам повезет, они даже смогут воспроизвести вашу проблему на своем оборудовании. Но это вряд ли случится, если вы укажите лишь общую и неконкретную информацию – в этом случае вам должно повезти еще больше, чтобы наткнуться на особо отзывчивого человека, который будет подробно расспрашивать вас о том, что именно произошло.

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

Сократите свой код до минимума, чтобы он по-прежнему воспроизводил ошибку. Это, помимо прочего, поможет вам изолировать проблему и контакт, вызывающие ошибку.

Итого

Проблемы, которые связаны с перезапусками ESP, активированными сторожевым таймером или исключениями, вполне решаемы. Аддон ESP8266 для IDE Arduino предоставляет подробную диагностическую информацию, которая поможет понять, в чем именно заключается корень проблемы. Перед проверкой ПО убедитесь, что у вас все в порядке с оборудованием. Чтобы узнать, в каком месте кода возникает ошибка, используйте расшифровщик ESP Exception Decoder. Если вы проделали все это, но по-прежнему не можете определить, в чем корень проблемы, пишите баг-репорт. Сделайте его максимально подробным (но не перебарщивайте). Будьте конкретны и изолируйте проблему. Затем спросите помощи у сообщества. Есть множество людей, которым нравится работать с ESP и которые хотят помочь в решении вашей проблемы.

См.также

Внешние ссылки