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
. 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.