INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
22.03.2021, 16:39 (Dieser Beitrag wurde zuletzt bearbeitet: 22.03.2021 16:42 von MicroBahner.)
Beitrag #1
ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Hallo,
den folgenden Text habe ich auch im Nachbarforum gepostet. Da gab's allerdings keine Reaktion. Hier wird ja etwas mehr mit den ESP gemacht. Vielleicht hat da einer auch eine Antwort zu dem im Text angesprochenen Problem mit den Linkeranweisungen.
--------------------------------
Derzeit bin ich ja dabei, die MobaTools für den ESP32 zu ertüchtigen. Da die MobaTools sehr viel mit Interrupts arbeiten, musste ich mich also auch mit den Interrupts auf ESP32 näher beschäftigen. Einige dieser Erfahrungen will ich hier mal teilen - vielleicht kennt die ja doch der eine oder andere noch nicht alle. Und alles was ich erfahren musste, steht auch nicht in der Doku Wink

Dass man Interruptfunktionen ( und allen in ihnen aufgerufenen Unterfunktionen ) das Attribut IRAM_ATTR mitgeben muss, dürfte sich inzwischen rumgesprochen haben ( das es u.U. auch ohne geht vielleicht noch nicht so, aber dazu unten mehr ).
Vielleicht nicht ganz so bekannt ist die Tatsache, dass konstante Tabellen/Arrays die in Interrupts genutzt werden, das DRAM_ATTR benötigen. Und zwar auch dann, wenn sie innerhalb einer ISR als lokales Array definiert werden. Der Compiler wertet hier das IRAM_ATTR der Funktion nicht aus. Das 'const' weglassen hilft nicht, da der Compiler selbsständig erkennt, dass die Tabelle nicht verändert wird, und sie deshalb als Konstante im Programmspeicher ablegt. Aber das steht ja noch alles in der Doku Wink.

Was da nicht steht, dass eine switch-Anweisung in einer ISR nicht mehr als 4 case-Blöcke haben darf. Bei mehr raucht's auch . Ich vermute, dass der Compiler das bis zu 4 cases in Art einer if-Abfrage realisiert, während er bei mehr case-Blöcken eine Sprungtabelle einrichtet, und die dann wieder an der falschen Stelle (im Programm-Cache) ablegt. Hier habe ich aber keinen Weg gefunden, ihm das DRAM_ATTR unterzujubeln. In der Esp-IDF kann man das wohl dem Linker mit speziellen Linkerfiles mitteilen, aber wie und ob das in der Arduino-IDE geht ... ???

Das tückische an der Sache ist, dass der Absturz nicht sofort passiert, wenn der Interrupt auftritt. Das kann u.U. lange dauern oder gar nicht passieren. Ursache ist ja, dass der ESP32 einen externen Flash-Speicher hat. Die Programme werden aber aus einem Cache ausgeführt, der vom Flash versorgt wird. Solange alles im Cache abläuft, und kein Flash-Zugriff notwendig ist, passiert nichts. Wann da ein Cache-Miss auftritt ist nicht vorhersehbar.
Eine Möglichkeit diese Situation zu provozieren (und damit zu testen ob die ISR 'sauber' ist) ist aber die EEPROM-Lib. Da der ESP32 kein echtes Eeprom hat, werden die Werte im Flash gespeichert. Zwar nicht sofort, denn die Schreibaufrufe der Lib legen die Werte erst in einem Pufferbereich ab. Erst mit EEPROM.commit() (Was es auf den AVR's gar nicht gibt) werden die Wert im Puffer in den Flash geschrieben. Bei diesem Flashzugriff ist der Programmcache deaktiviert. Wenn also nun ein Interrupt auftritt der nicht 'sauber' ist, kommt es zur Exception:
Zitat:Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)

Wen's interessiert, der kann das an dem kleinen angehängten Sketch nachvollziehen. Der macht nicht viel sinnvolles sondern dient nur zur Demonstation. An einem Pin wird ein 5kHz Signal erzeugt, und an dessen Flanke wird ein Interrupt erzeugt. In der ISR gibt es Zugriff auf eine Tabelle und eine switch-Anweisung - also beste Voraussetzungen für einen Absturz Wink.
Code:
// TestSketch für das Interrruptverhalten des ESP32

#include <EEPROM.h>
// Einige Ausgangssignale, wenn man den Ablauf mit einem LA nachvollziehen will
const byte tonePin = 13;        // Hier wird das 5kHz Signal erzeugt
const byte irqPin = 14;         // = HIGH während die ISR läuft
const byte commitPin = 15;      // = HIGH während der commit läuft
volatile byte switchVar;
volatile byte switchResult;

//void testISR() {
void IRAM_ATTR testISR() {
    //static volatile byte bitTab[] = { 5,4,3,2,1,0 };  //<<- ohne volatile schmiert die ISR ab
    //static const byte bitTab[] = { 5,4,3,2,1,0 };   //<<- Auch wenn man dieses Zeile aktiviert
    static const DRAM_ATTR byte bitTab[] = { 5,4,3,2,1,0 };   //<<- So geht's
    digitalWrite( irqPin, HIGH );
     switch ( switchVar ) {
      case 0:
        switchResult = bitTab[switchVar];
        break;
      case 1:
        switchResult = bitTab[switchVar];
        break;
      case 2:
        switchResult = bitTab[switchVar];
        break;
      case 3:
        switchResult = bitTab[switchVar];
        break;
      /*case 4: // wenn case 4 aktiv ist, gibt es auch eine exeption
        switchResult = bitTab[switchVar];
        break; */
      default:
        switchResult = -1;
        ;
    }
    delayMicroseconds(15);
    digitalWrite( irqPin, LOW );
}
void setup() {
    Serial.begin(115200);
    EEPROM.begin(512);
    pinMode( irqPin, OUTPUT );
    pinMode( commitPin, OUTPUT );
    ledcWriteTone( 0, 5000 );
    ledcAttachPin( tonePin, 0 );
    attachInterrupt( tonePin, testISR, RISING );
}

void loop() {
    static int loopcnt = 0;
    loopcnt++;
    if ( ++switchVar > 5 ) switchVar = 0;
    Serial.printf( "Switch=%d, Result=%d, loopCnt=%d\n\r", switchVar, switchResult, loopcnt );
    EEPROM.write( switchVar, loopcnt );
    digitalWrite( commitPin, HIGH);
    EEPROM.commit();
    digitalWrite( commitPin, LOW );
    delay(1000);
}

Grndsätzlich erlaubt es der ESP auch, Interrupts ohne IRAM_ATTR zu realiseren. Bei der Registrierung eines Interrupts können Flags mitgegeben werden, die das Verhalten des IRQ bestimmen. Eines dieser Flags ist das IRAM-ATTR Flag, mit dem man dem System sagt, dass die ISR im IRAM liegt. Ist das Flag nicht gesetzt, so wird die ISR während eines Flash-Zugriffs nicht aufgerufen. Bei ISR, die auch mal eine Verzögerung vertragen können, könnte man das machen. Der Arduino-Core setzt diese Flag aber grundsätzlich bei den attachInterrupt Aufrufen. Da müsste man dann schon tieferliegende API-Aufrufe nutzen, die es erlauben dieses Flag eben nicht zu setzen.

Im Anhang gibt's noch ein .c File. Wenn man das in den Sketchordner von obigem Sketch reinkopiert, wird der attachInterrupt nicht mehr als 'im IRAM' gekennzeichnet. Dann funktioniert der Sketch immer, auch ganz ohne IRAM_ATTR. Der Interrupt kann dann aber durchaus mal um einen mittleren 2-stelligen ms Zeitraum unterdrückt sein.


Angehängte Datei(en)
.c  ESPgpio.c (Größe: 9,98 KB / Downloads: 27)

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
22.03.2021, 17:00
Beitrag #2
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Hallo Franz-Peter,

das dürfte auch nebenan kein Desinteresse gewesen sein, sondern die Tatsache, dass wohl keiner so tief in die den ESP32 eingestiegen ist.
Hoffentlich hast Du hier mehr Glück.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
22.03.2021, 17:09
Beitrag #3
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Hallo Tommy,
ja, dachte ich mir schon. Aber nachdem es hier ja sogar eine eigenes Unterforum für die ESP's gibt ... schaun' mer mal Wink

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.03.2021, 16:47
Beitrag #4
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Klasse, danke schön für das Weitergeben Deiner Informationen! So was sucht man im Zweifel tagelang, wenn einem der schöne ISR unregelmäßig abraucht.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.03.2021, 20:45
Beitrag #5
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Diese Infos brauch ich tatsächlich auch, und ich bin aus Faulheit im anderen Forum nicht unterwegs - es wird eh dauernd wegen Crosspostings rumgemeckert Tongue

In der heutigen Zeit ist gesunder Menschenverstand so etwas Ähnliches wie eine Superkraft - aber keine nützliche.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.03.2021, 20:46
Beitrag #6
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
Wenn man beide ordentlich aufeinander verlinkt meckert eigentlich keiner.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
24.03.2021, 09:18
Beitrag #7
RE: ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;)
(23.03.2021 16:47)miq19 schrieb:  So was sucht man im Zweifel tagelang, wenn einem der schöne ISR unregelmäßig abraucht.
Kann ich bestätigen Wink - vor allem die Sache mit dem switch hat mich eine Weile beschäftigt.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  SHT30 an Wemos D1 Mini ESP32 Mirkan 6 248 10.05.2021 09:59
Letzter Beitrag: Mirkan
  ESP32 und sms kpc 25 1.229 10.05.2021 01:51
Letzter Beitrag: kpc
  ESP8266, Frage zu Void Loop Bobo83600 3 228 04.05.2021 17:50
Letzter Beitrag: Tommy56
  ESP32 access point: Browser Variablen einlesen FoxFactoy 1 198 03.05.2021 11:44
Letzter Beitrag: Tommy56
  ESP32 in Verbindung mit MCP23017 Kymmenen 17 732 02.05.2021 19:34
Letzter Beitrag: Tommy56
  ESP32 Flash Mode setzen Itsme 10 545 01.05.2021 20:04
Letzter Beitrag: Itsme
  Client(ESP8266) und Webserver(ESP32) Dahabcon 14 1.063 25.04.2021 20:32
Letzter Beitrag: Tommy56
  TTGO ESP32 SIM800L Pinout Stromversorgung pcfritz 1 397 18.04.2021 14:40
Letzter Beitrag: hotsystems
  ESP32 Daten aus HTML Roger100499 11 958 15.04.2021 15:00
Letzter Beitrag: Tommy56
  Erfahrungen mit ESP32 und WLAN/MQTT oder was ich beobachtet habe... Arduino4Fun 23 4.336 09.04.2021 16:15
Letzter Beitrag: amshh

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste