Dev-Branch

Es gibt jetzt, wie kürzlich diskutiert, einen dev-Branch.
Hier werden künftig neue Features zum Test eingebracht, ehe sie dann in den Master kommen.
Wäre schön, wenn sich ein paar Leute am Testen beteiligen würden. Ansonsten gilt: Es sollte einem bewusst sein, dass es der dev-Branch ist :slight_smile:.

Los geht’s mit Bugfix/heap handling by laszloh · Pull Request #204 · biologist79/ESPuino · GitHub.
Dazu habe ich zwei Anmerkungen

  1. Relativ am Anfang des Projektes hatte ich mal das Problem, dass der statische Speicher voll war. Durch ich glaube insbesondere das Allokieren der Audiolib auf dem Heap hat sich das deutlich entspannt. Aber ich habe damals so ziemlich alles, was nicht bei drei auf dem Baum war, auf dem Heap allokiert, damit das mit dem statischen Speicher nicht nochmal passiert. Weil von den Stack Traces konnte ich genau Null darauf schließen, dass der Speicher voll ist und es hat eine ganze Weile gedauert, bis ich rausgefunden habe, dass der Speicher das Problem ist.

  2. Es ist eine Anpassung drin, bei der die ID der RFID nicht mehr auf dem Heap angelegt wird. Vielleicht verwechsele ich es auch aber ich meine, das hatte uns mal vereinzelt Probleme gemacht (ohne Heap), dass der Speicherbereich verwaist war (bin jetzt aber auch zu faul, in den alten Commits zu suchen).

3 „Gefällt mir“

Hi Torsten,
Super, die Dev Branch freut mich. Ich werde die Tage meine pr auf diese umschwenken.

Zu 1, da habe ich das genau andersrum bis jetzt gehalten. Du musst bedenken, wir haben in der esp32 keine MMU (memory managment unit), somit ist heap Fragmentierung ein Problem. Wenn viele Speicherbereich oft allociert und wieder freigegeben werden entstehen die Löcher im Heap. Ob das ein Problem wird oder nicht ist aber schwer (bis gar nicht) vorhersehbar. Und dann schlagen malloc im Feld fehl, obwohl genug heap da wäre, aber halt nicht in einem durchgehenden Bereich. Auch findest du mit heap nur zur Laufzeit raus, ob dir der Speicher ausgegangen ist, was meist nicht der beste Augenblick ist :smiley:. Bei unserem System ist es ja nur nervig, wenn sich der ESP alle 3 Tage neu starten, aber es gibt andere Systeme da wäre das „nicht toll“.
Bei embedded System bevorzuge ich aus dem Prinzip den statischen Speicher (und dem Stack) zu verwenden, wo es nur geht. Statisch hat den Vorteil dass du ein Problem schon beim ccompilieren siehst. Stack ist ein wenig unangenehm da die Nutzung nicht zu Compiler time zu sehen ist.
Beim ESP haben wir ja noch da Glück, dass wir mehr als 2k RAM haben (als bei unsere kleinen Bruder und Schwester im atmega) und der heap da ist, wenn er für dynamische Daten verwendet werden muss (zB für die Playlist). WROVER mit seiner 4 / 8 MB RAM ist natürlich ein purer Luxus (auch wenn der Zugriff auf den externen RAM um einiges langsamer ist).

Dein Problem kann natürlich sein, wenn auf der einen Seite viel von statischen Bereich und belegt auf der anderen von Stack. Dann geht einem der Heap aus (auf den auch die Stacks von den FreeRTOS Tasks leben). Wenn dann jemand mehr dynamischen Speicher haben will als es verfügbar ist, wird malloc fehl schlagen und dann gibt es die interessanten Ellenlangen Stacktraces tief im FreeRTOS hinein.

Aktuell haben wir beim den WROOM knapp 65k freien Heap nach der ersten Wiedergabe. Ich denke das ist ausreichend, ich habe bis jetzt keine Aussetzer bei der Wiedergabe von mp3 bemerkt.


Zu 2 kann ich nach ein wenig Geschichtsforschung, aka Blame (nein nicht das Manga) etwas berichten. Ja, früher war es notwendig strdup zu nutzen, weil ihr im Code by-reference (aka Pointer) statt den Inhalt in die Queue geschreiben habt. Dann ist es natürlich notwendig dass die Variable entweder global oder im heap liegt.

Zb hier wird die Adresse und nicht der Inhalt vom Speicherbeireich wohin _rfidId zeigt in die Queue geschrieben (genauer gesagt, ihr schreibt den Inhalt von _rfidId in die Queue und die ist die Adresse von dem strdup Befehl). Wäre das eine lokale Variable hätten wir hier ein Problem (gelinde gesagt), da auf ein ungültigen Adressberech zugegriffen wird.

https://github.com/biologist79/ESPuino/blame/9f4bd4d49716d649d4980f22ab62ad371593745f/src/main.cpp#L953

Ich schaue mir gleich nochmal die xQueueSend in den aktuellen Code an, aber ich bin mir recht sicher, dass wir überall by-value übergeben (ansonsten würde sich die Empfangsseite mit einer Access-Violation übergeben).

edit: Ja, alles außer der aktuellen implementation der Playlist wird by-Value übergeben. Und di ePlaylist ist gewollt mit by-Reference.

2 „Gefällt mir“

Bei mir läuft der dev-branch (mit Arduino 2) super stabil und ich werde heute auch das System im Kinderzimmer updaten (Härtetest).
Wärst du damit einverstanden die Led-Struktur-Überarbeitung in den dev-Branch aufzunehmen wenn ich das noch bisschen aufgeräumt, kommentiert und wieder auf die reinen Struktur-Änderungen reduziert habe?
(Siehe separate Unterhaltung im LED-Thread : LED-Verbesserungen / Rework - #49 von laszloh)