• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Скетч выкидывает исключение - как понять где?

SuperBoss

Member
Друзья,

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

Reset reason: Hardware Watchdog
Reset info: Fatal exception:4 flag:1 (WDT) epc1:0x40000f68 epc2:0x00000000 epc3:0x40000f68 excvaddr:0x00000000 depc:0x00000000

Согласно перечню прерываний это вот это вот:
Level1InterruptCause
Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register

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

Поможите советами :)

Использую Arduino IDE с загрузкой в WeMos D1 R2 по Wi-Fi.....
 

Юрий Ботов

Moderator
Команда форума
Это же ватчдог... он где угодно может исключение дать, он же по времени срабатывает. Выключите его (ESP.wdtDisable();) или время от времени "кормите" (ESP.wdtFeed();)
 

SuperBoss

Member
Это же ватчдог... он где угодно может исключение дать, он же по времени срабатывает. Выключите его (ESP.wdtDisable();) или время от времени "кормите" (ESP.wdtFeed();)
Да, это хардверный сторожевой пес. Но похоже, что срабатывает он не из-за недокорма. Хардверный срабатывает через 6 секунд, до него должен сработать софтверный на 3-й секунде.
Насколько я понимаю, wdtDisable отключает только программный контроль, а аппаратный неотключаемый.
 

nikolz

Well-known member
Не надо отключать. Делайте его рестарт особенно в циклах.
 

SuperBoss

Member
Не надо отключать. Делайте его рестарт особенно в циклах.
Если применяется чужая библиотека, то кормить псину в ней никак. Я столкнулся с такой проблемой с DHT.h. Там пришлось именно отключать программную псину, поскольку некоторые циклы иногда работают больше 3-х секундов.

Но тут проблема не в софтверном псе, а в хардверном псе, который явно указывает на какую-то проблему с прерыванием. Но что оно значит и как найти место ее вызывающее - непонятно.
 

nikolz

Well-known member
Если применяется чужая библиотека, то кормить псину в ней никак. Я столкнулся с такой проблемой с DHT.h. Там пришлось именно отключать программную псину, поскольку некоторые циклы иногда работают больше 3-х секундов.

Но тут проблема не в софтверном псе, а в хардверном псе, который явно указывает на какую-то проблему с прерыванием. Но что оно значит и как найти место ее вызывающее - непонятно.
А разве исходников нет?
 

nikolz

Well-known member
поставьте вывод времени исполнения операторов и посмотрите где вывалится.
 

SuperBoss

Member
Похоже, что находится ошибка вызывающая эксепшн связанный с прерыванием :)
Люди с этого форума уже сталкивались с подобной напастью.

Проблема складывается сразу из трех факторов:
1. Наличие delay в loop;
2. Использование внешнего прерывания;
3. Использование стандартного web-сервера.

Собственно все три фактора есть и в моем скетче. Думаю как обойти проблем-с.
 

SuperBoss

Member
Так, похоже, что симптом частично подтвердился. На Delay в loop никак не реагирует. А вот совместное использование <ESP8266WebServer.h>, возможно <WiFiClient.h> и любого вида прерывания приводит рано или поздно к глюку и вываливанию с прерыванием. Причем реагирует как на внешнее прерывание через AttachInterrupt, так и на присоединение к таймеру через Ticker.
Т.е. если в коде есть любое прерывание, даже если оно локализовано четко в одном участке когда (через Attach/Detach) и где-то крутится server.handleClient(), то через минут 15-40 приезжает эксепшн. Если плата подключена к USB то она тупо зависает, если стоит сама по себе то перезагружается.
Прямо какая-то интересная мистика.

PS. Похоже, что виноват все же не ВебСервер однака. Без него тоже выскочило, правда гонялся скетч часов 5 или 6.

PSS. Похоже, что виноват таки не вебсервер. Вообще, как оказалось, в esp8266 под Arduino есть существенный косяк, связанные с любыми прерываниями и любой коммуникацией через Wi-Fi.
Фишка в том, что коммуникации очень важны по времени и там есть неотключаемые прерывания. Что в общем-то норм. Но вот пользовательские прерывания страдают от этого, в результате любое пользовательское прерывание, вызванное во время любой коммуникации (а именно там прерывания и требуются) ведет к возникновению описанного выше исключения. Что-то там связано с тем, что обработчик прерывания, т.е. функция используемая для вызова при наступлении прерывания должна быть загружена в памяти. Видимо как-то там на тайминги завязано.
Лечится все это весьма просто:
1. Добавляем макрос ICACHE_RAM_ATTR в описание функции, например так void ICACHE_RAM_ATTR resolver() { наш код }
2. Прописываем функцию из пункта 1 выше того места, где происходит AttachInterrupt или attach объекта Ticker.

По-идее должно работать. Но я буду еще тестировать.

PSSS. Все равно вылетает :-\
 
Последнее редактирование:

SuperBoss

Member
Ха, вопрос так и не решился на самом деле. Проблема присутствует. Вылетает WDT Reset без предварительного программного пса. Прерывания тут не причем. Возможно стоит переработать скетч с нуля. И возможно, что проблема уйдет. Выкину некоторые библиотеки, посмотрю, как пойдет дальше.
По этому поводу есть не один крик о помощи, например вот 4 ways to eliminate ESP8266 resets
 

nikolz

Well-known member
Ха, вопрос так и не решился на самом деле. Проблема присутствует. Вылетает WDT Reset без предварительного программного пса. Прерывания тут не причем. Возможно стоит переработать скетч с нуля. И возможно, что проблема уйдет. Выкину некоторые библиотеки, посмотрю, как пойдет дальше.
По этому поводу есть не один крик о помощи, например вот 4 ways to eliminate ESP8266 resets
В документации есть такое предупреждение:
upload_2016-9-5_19-52-52.png
 

SuperBoss

Member
@nikolz
Ну, собственно RTOS нам пока не светит, поскольку пишем под Arduino. В обработчике прерываний ничего не пишу :) Памятью не двигаю.
Процессор стараюсь не загружать, тем более понавтыкал везде, где можно кормления пса. Но проблема в том, что он не срабатывает. Срабатывает сразу аппаратный. Вот, кроме капитального рефакторинга даже ничего на ум не приходит :)
 

SuperBoss

Member
Друзья,

Похоже, что таки нашел проблему. По всей видимости оно связано с подтвержденным багом Arduino esp8266 SDK. Проблема с интенсивным PWM и Wi-Fi коммуникацией. У меня гонялся fade встроенного светодиода - туда/сюда.

Во время рефакторинга код оптимизировал до состояния порядка 300 микросекунд на Loop. Теперь мне не очень понятно, стоит ли добавлять delay(xx) в loop или нет.

С одной стороны loop забивает циклы процессора nop-ами, в результате меньше гоняется логика, меньше нагрев и меньше потребление энергии. С другой стороны оно итак все холодное (+2 гр над внешней температурой).
 

nikolz

Well-known member
Друзья,

Похоже, что таки нашел проблему. По всей видимости оно связано с подтвержденным багом Arduino esp8266 SDK. Проблема с интенсивным PWM и Wi-Fi коммуникацией. У меня гонялся fade встроенного светодиода - туда/сюда.

Во время рефакторинга код оптимизировал до состояния порядка 300 микросекунд на Loop. Теперь мне не очень понятно, стоит ли добавлять delay(xx) в loop или нет.

С одной стороны loop забивает циклы процессора nop-ами, в результате меньше гоняется логика, меньше нагрев и меньше потребление энергии. С другой стороны оно итак все холодное (+2 гр над внешней температурой).
Пишите на Си (UDK) и без loop.
Будет все понятно и компактно.
 
Сверху Снизу