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 https://github.com/biologist79/ESPuino/pull/204.
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).

4 „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)

Habe heute wie folgt die Vorbereitung für Änderungen im DEV-BRANCH getroffen:

  • In meinem git account einen Fork von Torstens espuino gezogen
  • dort den dev branch als default gesetzt
  • bei mir lokal ausgecheckt (gecloned)
  • git remote add upstream zu biologist ESPuino.git
D:\_GIT_HUB\ESPuino_dev_fork>git remote -v
origin  https://github.com/NIKO-AT/ESPuino.git (fetch)
origin  https://github.com/NIKO-AT/ESPuino.git (push)
upstream        https://github.com/biologist79/ESPuino.git (fetch)
upstream        https://github.com/biologist79/ESPuino.git (push)
D:\_GIT_HUB\ESPuino_dev_fork>git merge upstream/dev
Already up to date.

Habe dann auch gleich meine Änderung zur Reaktivierung der Option „PLAY_LAST_RFID_AFTER_REBOOT“ in Verbindung mit WebStreaming gemerged.
Wegen asynchronen WiFi-Connect hat das ja nicht mehr funktioniert.

So nun zeigt mein Visual-Studio-Code alle geänderten Files:
image

Wie gehe ich jetzt richtig vor:
Kann ich die Files, die ich nicht committen möchte/soll, wie:

  • platformio.ini
  • extensions.json
  • RfidPn5180.cpp (hier habe ich das PW für mich eingetragen)
  • settings-lolin_d32_pro_sdmmc_pe.h
  • settings.h

vom committen ausschließen indem ich diese zu gitignore hinzufüge?

platformio.ini
.vscode/extensions.json
src/RfidPn5180.cpp
src/settings-lolin_d32_pro_sdmmc_pe.h
src/settings.h

Dann würde ich bei [Commit] Dropdown: „Commit and Push“ wählen
GGF. vorher die Files Bereitstellen.

Warte nun auf Bestätigung bzw. Korrektur der Vorgangsweise.
VG & Schönen Abend

Du solltest nur die Änderungen „stagen“, die du committen möchtest. Dazu verwendet man git add oder git add --patch/git add -i (nützlich zum selektiven „Aufdröseln“ mehrerer Änderungen in einer Datei). In VSCode gibt es da sicherlich auch entsprechende Optionen in der GUI, die ich aber spontan nicht weiß.

Alles was „gestaged“ wurde landet dann bei git commit im Commit. Der Rest bleibt als „unstaged change“ auf der Platte (außerhalb von Git).

In die .gitignore sollten nur Dateien aufgenommen werden, die dauerhaft nie in Git getracked werden sollen.

Mehr Infos siehe: Git - Änderungen nachverfolgen und im Repository speichern.

Benutzerdefinierte Parameter wie das Passwort für RFID sollten eigentlich aus der CPP-Datei raus in eine ungetrackte Config-Datei (die würde dann in der .gitignore stehen). Das wäre ein Fall der durch meinen Ansatz mit KConfig gut abgedeckt werden würde. Aber das ist ein anderes Thema…

1 „Gefällt mir“

Vielen Dank!

Nachdem mein erster PR

Lost feature „PLAY_LAST_RFID_AFTER_REBOOT“ for webstreaming (local m3u file)

bei Torsten aufscheint, dürfte ich alles richtig gemacht haben.

Habe heute den aktuellen Branch getestet & bin in kleine Fehler reingelaufen. Außerdem gibt es jetzt viele Compiler Warnmeldungen (die auch alle Sinn machen aber scheinbar harmlos sind).
Einen Teil der konnte ich fixen:

Einige Warnmeldungen bleiben noch. Idealerweise gibt es keine Warnungen beim Kompilieren.
Wer kann lösen?

2 „Gefällt mir“

Ah verdammt. Der Fehler in Common.h ist durch mein PR rein gekommen. Ich hatte da ein Commit nicht gepusht gehabt… Danke für’s finden & fixen.

Die Warnungen wegen snprintf kann ich mir heute Abend anschaue. Grundsätzlich sind die harmlos, ich würde aber ungerne alle trunctation warnings mit einem gcc-flag abschalten.

edit: Um die Warnungen von snprintf zu lösen, könnten wir eine eigene Printf-Funktion im Logger bereit stellen. Ich habe kurz eine Lösung zusammengeworfen: Add printf wrapper for Logging · laszloh/ESPuino@45a70de · GitHub

Kommentare sind willkommen, bevor ich den Code an gefühlt 200 Stellen modifiziere :smiley:

1 „Gefällt mir“

+1 für den Print-Wrapper!

Allerdings finde ich folgende Version ein bisschen schöner/übersichtlicher (allerdings ungetestet). Vor allem sehe ich aktuell keinen Grund warum der lokale Puffer static sein müsste.

int Log_Printf(const uint8_t _minLogLevel, const char *format, ...) {
	char loc_buf[128];	// Buffer size selected so that most messages fit
	char *buf = NULL;

	int len;
	va_list arg;
	va_start(arg, format);

	// try to use local buffer
	len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg);

	if (len < sizeof(loc_buf)) {
		va_end(arg);
		Log_Println(loc_buf, _minLogLevel);
		return len;
	}

	// local buffer is too small, use dynamic buffer
	buf = (char*)malloc(len + 1);
	if (!buf) {
		return -ENOMEM;
	}

	va_start(arg, format);
	len = vsnprintf(buf, len + 1, format, arg);
	va_end(arg);
	Log_Println(buf, _minLogLevel);
	free(buf);
	return len;
}
2 „Gefällt mir“

Die Funktion gefällt mir, den werde ich übernehmen :smiley:. Static ist wirklich nicht notwendig und das retry-on-fail ist elegant. Ein Punkt was mir aber aufgefallen ist, vor va_start muss zwingend va_end aufgerufen werden, wenn die Variable schon einmal verwendet worden ist.

Die Branch ist zum großen Teil fertig, aber Achtung ich Ändere da teilweise mit force push: GitHub - laszloh/ESPuino at bugfix/snprintf_warning

Hier auch eine Frage an euch und Torsten @biologist, wie wollt ihr so eine große Änderung haben? Ein einzelnes Commit pro Feature (also zB 1 Commit für die Printf und 1 für die Umstellung aller Log_Prints) oder, wie aktuell, viele kleinere Commits die die einzelnen Dateien modifizieren?

1 „Gefällt mir“

Mir ist ein einzelnes Commit ehrlich gesagt lieber.

Das dynamische Allokieren bei größerem Speicherbedarf kann zu einem Fragmentieren des Heaps führen.

Hm, gute Frage. Prinzipiell finde ich persönlich einzelne Commits schöner. In so einem Fall wie hier, wo es um eine „treewide“ Änderung geht, die überall gleich aussieht, wäre ein Commit zum Einführen der Funktion, einer zum Umstellen aller Logs auf die neue Funktion und einer zum Löschen der alten Funktion auch denkbar.
Du hast ja aber auch noch ein paar andere Fixes in deinem Branch (fehlende Übersetzung, etc.) was idealerweise in einem eigenen Commit wäre. Muss aber natürlich nicht…

Deshalb wird ja für „kleine“ Logs auch ein statischer Puffer verwendet. Vielleicht müsste man mal schauen ob man alle Log-Strings auf dem Stack erzeugen kann. Ich weiß jetzt nicht wie lange die Logs üblicherweise sind.

Die einzelnen Logitems laufen ja zuerst alle zuerst durch den LogBuffer. Der hat 200 Zeichen und meines Erachtens reicht das pro Logeintrag auch völlig aus. Der wird einmalig auf dem Heap allokiert und dann an ganz vielen Stellen verwendet.

Mir ist ehrlich gesagt unklar warum man das jetzt (halb-)dynamisch machen will. Und da bin ich der gleichen Meinung wie @tuniii, dass das zu Heap-Fragmentierung führen kann. Auch wenn es ggf. selten passiert: Wozu das Risiko eingehen?

Also von mir aus können wir es auf dem Stack machen und limitieren die Größe halt, wie aktuell schon, auf 200 Zeichen (oder von mir aus halt 255). Was drübergeht wird halt abgeschnitten.

Wenn der Puffer sowieso dauerhaft allokiert bleibt, sehe ich keinen Grund den auf dem Heap zu haben.

Ja, das klingt sinnvoll. Ob der Nutzen hier die dynamische Allokierung rechtfertigt ist eher fraglich. Die einfachere Variante ist im Zweifelsfall die bessere…

2 „Gefällt mir“

Die dynamische Allkoierung war als Verbesserung gedacht gewesen. FUnktioniert natürlich auch ohne :slight_smile:.

Ich habe es jetzt so gelöst, dass wir keine dynamische Allokierung haben. Ein Logeintrag ist damit auf max 200 Zeichen begrenzt. Um den User über das Abschneiden zu informieren, füge ich „…“ am Ende des Strings hinzu. Diese sind nicht Teil der 200 Zeichen

Damit schaut ein extra langer Logeintrag so aus:

[ 580 ]  This will be a long string: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum posuere tellus eget placerat cursus. Morbi commodo risus justo, non porttitor orci malesuada quis. Pelle...

Wenn ihr zufrieden damit und den anderen Änderungen seit, starte ich den PR mit diesen: Commits · laszloh/ESPuino · GitHub

3 „Gefällt mir“

Hallo ,
Problem mit Webzugriff bei der DEV:
Ich habe seit einiger Zeit Probleme beim Zugriff mittels WebGui , obwohl WiFi ok ist und Webradio läuft.
Ich konnte es bis eben nicht nachvollziehen. Es passierte das erste Mal bei einem Test von Dateiupload im SPI-Mode. Der 1. Upload mit 24 Dateien funktionierte einwandfrei ohne Datenverlust, der 2. Upload mit 22 Dateien brach mit der Meldung
[ 60005 ] RSSI: -65 dBm
[ 66002 ] Der Webtransfer wurde aufgrund von Inaktivität beendet.
[ 66014 ] Kontroll-Kommando empfangen via Queue: 3
ab.
Danach konnte ich auf die WebGui nicht mehr zugreifen , auch nach Reset oder Abschalten nicht. Habe dann wieder auf SD_MMC geändert und eben passierte es wieder. Wieder nach Datei-Upload, obwohl der einwandfrei funktioniert hat. Mein Espuino rebootete von alleine , danach kein Webzugriff mehr. Abschalten und Reboot brachte keine Linderung, Webradio ok. Ich habe dann mittels Taste Wifi OFF/ON
geschaltet , danach ging Webzugriff.

Habe diese Meldung gehabt:
#[ 106642 ] Synchronisiere Uhrzeit via NTP…
[106642][E][ESPmDNS.cpp:148] addService(): Failed adding service http.tcp.

Hat das sonst noch jemand beobachtet? Ich verwende im Moment Rev 20230328-1
Ich glaube es passiert beim Upload und werde es später nochmal versuchen nachzustellen, muss jetzt weg.

VG

Ich habe gestern den größeren Logging-Umbau eingecheckt - danke an @laszloh an dieser Stelle.
Bei mir war es allerdings dann notwendig „Clean All“ auszuwählen, da ich sonst einen iram-Fehler bekommen habe.

@SZenglein Das hat leider größere Auswirkungen auf das Logging für die Behandlung mehrerer WLANs.

Ist kein Problem, das Logging muss ich eh noch machen.
Den PR passe ich dann dem aktuellen ‚dev‘ an.

Grundsätzlich finde ich die Verwendung des neuen Loggings viel besser.

Ich versuche gerade eine Modifier-Karte in der Web-UI anzulernen, das geht aber nicht mehr!

Klicke ich auf den Tab „Modifikation“ wird die gleiche Auswahl wie bei „Musik“ angezeigt.
Das Problem ist scheinbar mit dem Commit

#215 from fschrempf/execute-commands

reingekommen.Ziehe ich die management.html davor ist Alles OK. @Joe91 oder habe ich von der Bedienung her etwas übersehen? Ich denke aber das ist ein dicker Bug!