ESP32 - Interrupts zum Neustarten verwenden

Moin,

ich bin auf der Suche nach einer Möglichkeit, den ESP32 mit einem Interrupt neu zu Starten. Wenn ich jedoch

ESP.restart();

in der im Interrupt definierten Funktion aufrufe, hängt sich der ESP auf.
Der Stack:

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x4008c0a0  PS      : 0x00060534  A0      : 0x8008b1c3  A1      : 0x3ffbe650  
A2      : 0x3ffbd740  A3      : 0x3ffbc704  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00060523  A7      : 0x00000000  A8      : 0x3ffbc704  A9      : 0x3ffbc704  
A10     : 0x00000019  A11     : 0x00000019  A12     : 0x00000001  A13     : 0x00000001  
A14     : 0x00060521  A15     : 0x00000000  SAR     : 0x00000018  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core 1 was running in ISR context:
EPC1    : 0x401091dc  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x4008c0a0
Backtrace: 0x4008c0a0:0x3ffbe650 0x4008b1c0:0x3ffbe670 0x40089c53:0x3ffbe690 0x400dc759:0x3ffbe6d0 0x401148f6:0x3ffbe6f0 0x4010966d:0x3ffbe710 0x40084f5f:0x3ffbe740 0x400d6677:0x3ffbe760 0x400d1ac6

Ich denke, dass die ESP.restart(); Routine zu lange für eine ISR Funktion braucht und dadurch der WDT ausgelöst wird. Mir fällt aber keine andere Idee ein, wie ich den ESP mit einem Interrupt neu Starten könnte. Vielleicht hat hier ja jemand eine Idee. Danke euch!

Ja, verzichte auf den Restart() und setze einfach Deine Variablen auf den Initialwert zurück.
Das ist doch im Endeffekt was Du bezwecken möchtest.

Hast du zufällig asynchrone Funktionen am laufen?
Ich verwende den asynchronen Webserver und habe das gleiche Problem.
Deshalb verzichte ich vorläufig auf Interrupts.

Leider geht das nicht. Ich speichere Kalibrierwerte ins EEPROM. Und wenn ich dann neu Starte sollen die neuen Kalibrierwerte aus dem EEPROM geladen werden. Und das mache ich immer im Setup.

dann gib dieses "EEPROM laden" in eine Funktion, ruf diese aus dem setup auf, immer dann wenn du es wieder brauchst...

P.S.: EEPROM ist am ESP32 deprecated:

dann gib dieses "EEPROM laden" in eine Funktion, ruf diese aus dem setup auf, immer dann wenn du es wieder brauchst...

Genau so ist es

z.B.
void readEepromSettings() {
//hier EEPROM Daten einlesen
}

readEepromSettings() dann immer im Programm aufrufen, wenn Daten aus dem EEPROM geladen werden sollen.

oder:
void readEepromSettings(variable& a, variable& b, variable& c) {
//hier EEPROM Daten einlesen
}
wenn die Variablen nicht global sind

Okay, danke.
Ich habe das nicht versucht, da ich dachte, dass EEPROM.get noch länger dauern würde als ESP.restart();. Aber es geht doch. Danke!

Falls hier jemand über die Suchfunktion landet, hier eine Möglichkeit den ESP32 aus einer ISR heraus neuzustarten:

volatile bool doRestart=false;

void setup() {
  xTaskCreate([](void*p){for(;;){if(doRestart)ESP.restart();}},"Restart",configMINIMAL_STACK_SIZE,NULL,0,NULL);
  //(...)
}

Nestarten geht dann in der Interrupt Service Routine mit:

doRestart=true;
return;

gruß lorenz

Hab nochmal drüber nachgedacht und denke, dies ist die bessere Lösung:

TaskHandle_t RestartHandle;

void setup() {
  xTaskCreate([](void*p){vTaskSuspend(NULL);ESP.restart();},"Restart",configMINIMAL_STACK_SIZE,NULL,(3|portPRIVILEGE_BIT),&RestartHandle);
  //(...)
}

Auslösen des Neustarts dann mit:

xTaskResumeFromISR(RestartHandle);
return;

gruß lorenz

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.