• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

rapidshe

Member
Господа, всем привет)
Проблема с сторожевым таймером. Не могу вызвать оО
Хотя судя по гуглу у многих проблема наоборот - долгий цикл вызывает перезагрузку...

Изначально вспомнил о сторожевом таймере вспомнил после того, как начались зависания ЕСП от частой отправки данных на MQTT (т.е. в приложении IOTmanager жму на кнопку "+" для увеличения необходимой температуры на "1" и примерно после 6-7го раза происходит зависание. точнее не зависание, а ооооооооооооооооочень медленная работа ЕСП.
в loop стоит маячек и поначалу в мониторе порта он как бешенный отображается, а после появления проблемы буквально раз секунд в 30-50 наверное....
потом где то минут через 20 начинает шустро работать(по крайней мере маячек в монитор шлется шустро), но уже без связи с mqtt. да и локальный веб сервер не поднимается.

в начале setup прописал
ESP.wdtDisable();
ESP.wdtEnable(3200);

а в loop ESP.wdtFeed();

пробовал еще ESP.wdtEnable(WDTO_8S);


каждый раз, когда вызывается ESP.wdtFeed() мне выводится маячек.
И несмотря на то, что ESP.wdtFeed() вызывается раз секунд в 20 (хотя сторожа ставил на 3,2с и 8с) перезагрузка не произходит...почему?
 
Последнее редактирование:

pvvx

Активный участник сообщества
пробовал еще ESP.wdtEnable(WDTO_8S);
Бесполезная функция с void параметром:
Arduino/Esp.cpp at master · esp8266/Arduino · GitHub

Как и void EspClass::wdtFeed(void) { system_soft_wdt_feed();}
Код:
void ICACHE_FLASH_ATTR system_soft_wdt_feed(void)
{
    wdt_flg = false;
    WDT_FEED = WDT_FEED_MAGIC;
}
Всё это не работает, т.к. в SDK есть второй таймер, по которому производится анализ-эмуляция "WDT".
Если обобщить - управление WDT в Arduino IDE для ESP8266 не работает. Основная причина кроется в SDK от Espressif...
 
Последнее редактирование:

rapidshe

Member
Бесполезная функция с void параметром:
Arduino/Esp.cpp at master · esp8266/Arduino · GitHub

Как и void EspClass::wdtFeed(void) { system_soft_wdt_feed();}
Код:
void ICACHE_FLASH_ATTR system_soft_wdt_feed(void)
{
    wdt_flg = false;
    WDT_FEED = WDT_FEED_MAGIC;
}
Всё это не работает, т.к. в SDK есть второй таймер, по которому производится анализ-эмуляция "WDT".
Если обобщить - управление WDT в Arduino IDE для ESP8266 не работает. Основная причина кроется в SDK от Espressif...
т.е. вообще без вариантов? никак? но Arduino IDE вроде бы почти обычный компилятор и наверное можно какой то код в чистом виде задать....
 

pvvx

Активный участник сообщества
т.е. вообще без вариантов? никак? но Arduino IDE вроде бы почти обычный компилятор и наверное можно какой то код в чистом виде задать....
А где взять полные исходники SDK для управления WDT и дублирующей процедурой в task, проверяющей обработку за время флагов отработаки других функций и второго таймера, в регистрах WiFi блока, тоже участвующего в данном процессе?
Espressif не дает внутренности своего SDK и чипа никогда, пока это не раскрутят другие и не "выведут на чистую воду". У них там полный бардак и нарушение (с) - других причин для сокрытия потрохов SDK у них нет. Шарашкина контора... к ней и липнут такие-же горе писатели софта. :)
 
Последнее редактирование:

rapidshe

Member
А где взять полные исходники SDK для управления WDT и дублирующей процедурой в task, проверяющей обработку за время флагов отработаки других функций и второго таймера, в регистрах WiFi блока, тоже участвующего в данном процессе?
Espressif не дает внутренности своего SDK и чипа никогда, пока это не раскрутят другие и не "выведут на чистую воду". У них там полный бардак и нарушение (с) - других причин для сокрытия потрохов SDK у них нет. Шарашкина контора... к ней и липнут такие-же горе писатели софта. :)
печалька... ну хоть с причиной зависушек разобрался. но стремненько без сторожа. мало ли что....
 

pvvx

Активный участник сообщества
печалька... ну хоть с причиной зависушек разобрался. но стремненько без сторожа. мало ли что....
Я всего частично “ревесрил” куски SDK по поводу WDT, но они ещё сильно разнятся от версий SDK и общего подхода к его управлению не выработано… А далее, при наличии альтернативы от других производителей, заниматься раскопками глюка “ESP8266” не вижу смысла... Так что используйте метод “тыка” – так или сяк накидайте всякие процедуры с WDT и отдачу времени на обработку функциям SDK – вдруг сработает - заработает при ваших условиях как надо.
Вы не точно описали проблему - "не срабатывает WDT?" или наоборот "Срабатывает WDT и перегружает ...?"

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

Legantmar

New member
Всем привет!
Имею такую ситуацию:
с "периодичностью" от одного дня до 3-х (т.е. в случайное время) происходит перезагрузка по причине Hardware WDT Reset (по результатам rst_info* rinfo = ESP.getResetInfoPtr(); причина 1)
утечки памяти нет (по результатам ESP.getFreeHeap())
ставил 2 разных устройства с разными блоками питания, но с одинаковой прошивкой, ситуация аналогичная, перезагружаются оба (доп. конденсаторы по питанию 0,1мкф и 470мкф тоже не помогли) (да и в случае скачков напряжения или отключения причина возникает другая), т.е. дело скорее всего не в блоке питания.
Пробовал ставить ESP.wdtFeed() в основной Loop() и дополнительно в цикл проверки wi-fi и реконнекта - не помогло.
Вот теперь думаю о ESP.wdtDisable(); - пробовал поставить в Setup() - как только контроллер соединяется с wi-fi роутером через секунду происходит перезагрузка - замкнутый цикл ))
какие есть мысли? готов ответить на любые вопросы.
 

Legantmar

New member
добавил в setup()
ESP..wdtDisable();
ESP.wdtEnable(WDTO_8S);
и в loop ESP.wdtFeed();
как указано в верхнем в посте.
посмотрим, что из этого выйдет.
но есть предположение, что это влияет только на soft WDT и не влияет на hardware WDT (именно эта причина перезагрузки у меня вываливается).
 

Legantmar

New member
не помогло.
устройство простояло 25 часов, затем hardware WDT reset, затем продержалось 4 часа...
какие мысли? куда копать?
отключать часть кода?
или перезагрузки типа hardware wdt reset возникают у всех и это нормально? )))
 

Legantmar

New member
см. выше
утечки нет, писал об этом (но дефект памяти на уровне железа возможен. от этого никто не застрахован и никак это не проверить).
перезагрузка может произойти в любое время! в интервале: мин. 4 часа. максимально 3 дня
одновременно ставил 2 устройства с одинаковой прошивкой, но разными блоками питания..
оба перезагрузились через 3 дня, с разницей в 7! часов
в скрипте есть функция NTP времени и проверка Wi-Fi (кол-во попыток ограниченно программно)

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

Paul_B

Member
Ситуация следующая, есть 5 плат ESP8266, которые образуют сеть (как-то там подключаются между собой) и начинают передавать управляющие сообщения (естественно, с пробросом, если одна ESP подключена к другой, либо с одной на другую, если обе в одной подсети. Все устроено так, что со временем каждая ESP знает всех, кто участвуют в сети.
Но иногда происходит перезагрузка по wdt_reset, вот что в порту:
Код:
Send Client ip=192.168.1.115 message=/sms?func=state_ask&from_ip=192.168.1.74&from_chip=0EFC9F&from_module=0EFC9F&module_begin=38E464&module_end=B8C52E&id=151
Exception (29):
epc1=0x4021c8b2 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000004 depc=0x00000000
ctx: sys 
sp: 3ffffd30 end: 3fffffb0 offset: 01a0
>>>stack>>>
3ffffed0:  3ffebae4 00000000 00000000 4021c8b0 
3ffffee0:  3fff56cc 3fff31e4 3fff31e5 4021c93c 
3ffffef0:  00000036 00000000 00000000 4022efa6 
3fffff00:  4a01a8c0 40244ecb 3fff782c 00000000 
3fffff10:  00000000 00000036 3fffff80 3fff7ae2 
3fffff20:  3fff3388 3fff7ac4 3fff3470 4023316d 
3fffff30:  00000014 00000951 00000951 3fff3388 
3fffff40:  3fffdc80 3fff3f2c 3fff7f14 3fff426c 
3fffff50:  00000008 3fff3388 3fff7ac4 4022c7a1 
3fffff60:  3fffdc80 3fff3f2c 3fff7f14 4010453c 
3fffff70:  40249d6a 3fff3f2c 3fff7f14 40249d7c 
3fffff80:  3fff7ad4 3fff7ac4 00000002 00000000 
3fffff90:  40244c63 00000000 3fff7f14 4024bcd3 
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49 
<<<stack<<<
 ets Jan  8 2013,rst cause:4, boot mode:(3,7)
wdt reset
load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v614f7c32
~ld
А вот сама функция, на которой происходит сброс:
Код:
bool Send_Client(IPAddress ip, String Subj)
{
  WiFiClient client;
  Subj.replace(" ", "%20");
  Subj.replace("\"", ""); 
  client.setTimeout(2000);
  Serial.print("\n Send Client ip="+IP_to_String(ip)+" message="+Subj);
  if (client.connect(ip, 80))
     {
      client.print(String("GET ") + Subj + " HTTP/1.1\r\nHost: " + IP_to_String(ip) + "\r\nConnection: close\r\n\r\n");
      client.flush();
      client.stop();
      Serial.println("\n Sended OK");
      return(true);
     
     }
   Serial.println("\n Not Connect");
   return(false);
}
Я так подозреваю, что это происходит тогда, когда не может подключиться к плате по причине того, что та в это время передает сообщение.
Оращу внимание, что
Код:
client.setTimeout(2000);
не помогает, как и не помогает, выставленное в setup'е
Код:
ESP.wdtDisable();
Куда копать?
 

Paul_B

Member
Понаблюдал с помощью ESP.getFreeHeap().
Память утекает. Начинает на уровне 22-23кб, а близко к перезагрузке 2-3 кб.
Да, вызываются много функций, но вложения не больше 2-х, это отслеживаю. Куда может расходоваться память, а главное как ее восстанавливать?
 

rst

Member
Куда может расходоваться память, а главное как ее восстанавливать?
Её не надо восстанавливать. Надо:
1. Искать баги в своём коде.
2. Учиться писать оптимально (без такого отстоя: Subj.replace(" ", "%20"); Subj.replace("\"", "");).
3. Научиться обходиться без динамической памяти.
...и память перестанет утекать.
 

Paul_B

Member
Короче, утечку удалось победить после следующих действий:
1. Замена метода передачи с GET на POST, удаления client.stop() из функции передачи.

Код:
bool Send_Client(IPAddress ip, String Subj)
{
  WiFiClient client;
 
  Subj.replace(" ", "%20");
  Subj.replace("\"", "");
  client.setTimeout(1000);
  Serial.print("\n Send Client ip="+IP_to_String(ip)+" message="+Subj);
  if (client.connect(ip, 80))
     {
      client.print(String("POST ") + Subj + " HTTP/1.1\r\nHost: " + IP_to_String(ip) + "\r\nConnection: close\r\n\r\n");
      client.flush();
   //   client.stop();
      return(true);
   
     }
   Serial.println("\nNot Connect");
   return(false);
}
На сервере на каждый приход запрос отсылаю server.send ( 200, "text/plain", "...")ж
Код:
String InputHTTP()
{
  String message = "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments:" + String(server.args());
  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += "\n " + server.argName ( i ) + ": " + server.arg ( i );
  }
 
  Serial.println("\n" + Time_to_String("t") + " *** Input ***" +"\n" + message);
  if (server.hasArg("id"))
      server.send ( 200, "text/plain", "/OK?func=OK&from_id=" + server.arg("id"));
  return (message);
}
Что конкретно помогло не знаю, но совокупность этих действий победило утекание памяти.
Все тестировал всегда на 5 модулях, соединенных в сеть по методу клиент-сервер, т.е. на каждом модуле организован сервер и с остальными модулями каждый общается, как клиент. Раньше память 21кб утекала в течение часа и вызывала перезагрузку модуля, сейчас при активной пересылке сообщений свободная память может уменьшится до 19-20кб, но потом опять увеличивается до 21-22кб.
 
Последнее редактирование:
Сверху Снизу