Wenn ihr sowas wie JS, CSS oder HTML in euren Embedd-Projekten mit integriertem Webserver verwendet, baut ihr das dann als static const char JS[] Array ein? Welche Methoden nutzt ihr dafür? Ich mache das aktuell noch als ein Array, aber teilweise sind das 200-300 Zeilen und man muss höllisch aufpassen keinen Escape- oder Comment-Fehler zu machen. Ganz davon ab ist der Code nicht mehr lesbar...
:
Bearbeitet durch User
Entweder Du baust die automatische Datei-Konvertierung in Deinen Build-Prozess ein oder aber, da Du ja einen ESP32 nutzt, Du legst die Dateien auf einer eigenen Partition in einem Dateisystem im Flash ab und liest die Dateien dann per Storage API ein. Das Kopieren der Dateien in die Partition geschieht automatisch beim Build im esp-idf.
https://www.mikrocontroller.net/articles/Bin%C3%A4re_Daten_zum_Programm_hinzuf%C3%BCgen Was mit Binärdaten funktioniert klappt natürlich auch mit Text (HTML etc). Ich finde die Variante mit objcopy am Besten - kompiliert sehr schnell und funktioniert entkoppelt vom Sourcecode.
:
Bearbeitet durch User
Die Dateien liegen bei mir auf dem Dateisystem und werden über HTTP_GET aufgerufen.
1 | #include <ESPAsyncWebServer.h> |
2 | server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *req){ |
3 | req->send(LittleFS, "/settings.html", "text/html"); |
4 | });
|
Definitiv Files, keine C-Strings. Ansonsten bist du nur noch am kopieren. Und unübersichtlich ist es auch. Wenn du noch Platz und Ladezeit sparen willst lässt du dir die großen Files noch in einem Prebuild step in einen neuen Ordner zippen. Dann installierst du dir noch sowas wie den Live Server in VSC und kannst auch gleich noch vernünftig die Website anschauen und debuggen.
ich verwende einen Raw-String:
1 | const String htmlHeader = R"---(<!DOCTYPE HTML> |
2 | <head>
|
3 | <meta charset="utf-8"> |
4 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
5 | </head>
|
6 | )---"; |
Die Strings lassen sich mit += leicht konkatenieren und JavaScript code kann man einfach so runterschreiben.
Claus P. schrieb: > ich verwende einen Raw-String: > Die Strings lassen sich mit += leicht konkatenieren Das klappt halt nur bei kleinen Webseiten gut, weswegen es viele ESP-Beispiele nach dem Schema gibt. Aber sobald die Seite komplizierter wird, kann das zu schwer zu debuggenden Fehlern führen, weil der Speicher ausgeht oder zu stark fragmentiert. Dein HTML-Code liegt einmal im Flash, wird dann beim String-anlegen in den RAM kopiert, und jedes "+=" legt potentiell nochmal eine Kopie vom gesamten String im RAM an. Und die Antwort wird erst gesendet, wenn der ganze HTML-String fertig ist. Bei der Lösung als Dateien im LittleFS mit dem AsyncWebserver entfallen diese Probleme. Große Dateien werden Blockweise gestreamt, es ist immer nur der gerade versendete Chunk im RAM, der HTTP-Antwort-Header und die Ersten Daten wandern schon zum Webbrowser, bevor die ganze Datei überhaupt gelesen ist. Über die Template-Engine kannst du auch da dynamisch Werte/Texte einsetzen. => Für kleine Demo-Projekte kann man das mit den Strings machen, wenn absehbar ist dass es evtl. etwas umfangreicher wird, würde ich gleich auf eine skalierbare Lösung setzen, und mir das Umbauen später sparen.
Claus P. schrieb: > ich verwende einen Raw-String Dann brauchst Du aber noch ein sed für die Escapes. Alexander schrieb: > Die Dateien liegen bei mir auf dem Dateisystem Hab hier mal ein Template als Demo erstellt. https://www.mikrocontroller.net/topic/goto_post/8019977
Alexander schrieb: > Dann brauchst Du aber noch ein sed für die Escapes. Beim RAW-String? Da kannst du den String-Ende-Marker selber festlegen, und der darf aus bis zu 16 Zeichen bestehen. Da was zu wählen, was garantiert nie im HTML vorkommt, sollte möglich sein. Statt R"---(html)---" geht auch R"Aetioth3ee6eep5u(html)Aetioth3ee6eep5u"
Obelix X. schrieb: > Johann L. schrieb: >> #embed "datei.js" > > Wird das vom ESP32 Compiler unterstützt? Ist im C-Standard.
Johann L. schrieb: > Ist im C-Standard. In C23. Das ist noch ziemlich frisch; es dürfte noch sehr viele Compiler geben, die davon nichts wissen. https://en.cppreference.com/w/c/preprocessor/embed
Also bei mir schwankt das. Die meisten Webseiten bastle ich mir sowieso außerhalb des ESP, dann muss ich sie nur einmal in den Quellcode kopieren und kann sie anschließend "vergessen". Geschmackssache, ich habe am Ende gerne alles in einer einzigen Datei.
Weshalb sollte man sich Strings vom flash ins Ram kopieren ? Die sind doch auch gut im flash, gleichwertig, sofern der compiler das so kann.
Pandur S. schrieb: > Weshalb sollte man sich Strings vom flash ins Ram kopieren Copy&Paste-Geschichte. Es gibt Berge an Arduino-Beispielen nach dem Schema
1 | String response="<html>"; |
2 | response += "<head>"; |
3 | ...
|
Viele Leute übernehmen das ohne Nachzudenken, und schon existiert ein weiteres Beispiel nach dem Schema. Jetzt kommt noch die KI dazu, die mit all diesem Code trainiert wurde, und logischerweise wird die dann auch sowas ausspucken... Aus dem Teufelskreis werden wir nicht mehr herauskommen, fürchte ich. Aber egal, die nächste µC-Generation hat wieder mehr RAM und Rechenleistung, das ist sicher alles fein.
String ist nicht für statische Daten gedacht und legt bestimmt auch ein Objekt im Speicher an. Da ist dann echt das olle Array of Char passender. Wenn man das im make Prozess mit generieren kann, gibt es auch keine Probleme mit Zeichen, die vergessen wurden beim Escapes einfügen. Gibt es xxd auch für Windows (oder noch DOS) ? Ich habe unter Windows dafür HxD benutzt. Allerdings leider nicht aus dem Makefile, sondern im Handbetrieb. Könnte man statische Dateien nicht auch auf einen potenteren Server, der im Internet hängt auslagern und von da einbinden ? Oder blockt da der Browser aus Sicherheitsbedenken ? Den Kram gepackt im Speicher abzulegen bringt doch erst was, wenn die Platzersparnis den Platzbedarf der Entpackroutine übersteigt. Und zeitlich dürfte das Entpacken so gut wie immer verlieren. Was hier wunderbar funktioniert hat, ist die .html Dateien in dem Sinne zu packen, dass man alle Zeichen rauswirft, die nichts an der Darstellung im Browser ändern. Also auf Gliederungen durch Einrückungen und Zeilenumbrüche im Quelltext verzichtet und dem Browser gleich sagt, hier kommt UTF8, das kannst Du Punkt und dafür keine Umschreibungen wie
1 | ä |
mehr braucht. Auch dafür gibt es Software, die Dateien entsprechend tuned. Ehrlich gesagt, habe ich mir dieses Filesystem im ESP32 noch nicht angeschaut. Im Endeffekt, legt das doch bestimmt auch die Datem mit ein paar Verwaltungsdaten im Flash ab, oder ? Den Vorteil sehe ich dann, wenn ich öfter mal meine Software updaten muss, aber die riesigen Daten gleich bleiben, dann geht das flashen schneller. Die liegen doch bestimmt auch im Flash, oder ? Bzw. kann ich den Bereich für das Filesystem auf nahezu null schrauben, um den Platz dann für Daten, die sich in meinem Programmcode verstecken, frei zu machen ? Der ESP32 hat doch keine Harvard Architektur, bei dem die Daten mühsam vom Programmspeicher in den Datenspeicher geschafft werden müssten.
Flunder schrieb: > Könnte man statische Dateien nicht auch auf einen potenteren Server, der > im Internet hängt auslagern und von da einbinden ? Könnte man machen. Dann verliert man aber meiner Meinung nach genau den Vorteil eines solchen Systems. Alles Lokal und unabhängig von anderen Systemen zu haben. Du willst das Webinterface deiner Heizung ja evtl noch aufrufen wenn das Internet gerade nicht geht oder der externe Server gerade nicht erreichbar ist. Flunder schrieb: > Oder blockt da der Browser aus Sicherheitsbedenken ? Lies mal zu CORS (Cross-Origin Resource Sharing) nach. Geht schon. Flunder schrieb: > Den Kram gepackt im Speicher abzulegen bringt doch erst was, wenn die > Platzersparnis den Platzbedarf der Entpackroutine übersteigt. Und > zeitlich dürfte das Entpacken so gut wie immer verlieren. Entpackt wird ja nicht auf deinem uC. Sondern im Browser. Du sparst so auf 2 weisen. Der Controller braucht nicht so viel Speicher und du kannst es deutlich schneller übertragen. Geht wirklich verdammt schnell das entpacken. So hab ich schon mehr als 4MB Daten und viele JS Libraries in einem 2MB Controller abgelegt. Und da war noch das eigentliche Programm (Webserver,Applikation,...) dabei. Flunder schrieb: > Was hier wunderbar funktioniert hat, ist die .html Dateien in dem Sinne > zu packen, dass man alle Zeichen rauswirft, Ist verschwendete Liebesmühe. Wenn du die Datei komprimierst macht das so gut wie keinen Unterschied. Der HTML/JS Code schrumpft ziemlich extrem zusammen durch die Komprimierung. Flunder schrieb: > Ehrlich gesagt, habe ich mir dieses Filesystem im ESP32 noch nicht > angeschaut. Im Endeffekt, legt das doch bestimmt auch die Datem mit ein > paar Verwaltungsdaten im Flash ab, oder ? Ja klar. Ist ja nach System einfach ein FAT. Halt nicht auf SD Card sondern im Flash. Flunder schrieb: > Den Vorteil sehe ich dann, wenn ich öfter mal meine Software updaten > muss, Du kannst dadurch aussehen und Funktion komplett trennen. Ein Update des Webinterface bedingt dann kein neues Kompilieren. Du kannst einfach die neuen Dateien hochladen. Funktionserweiterungen die in Webinterface genauso. Nur Änderungen im CPP Programm musst du dann anders updaten. Wobei das auch über OTA möglich ist. Außerdem macht es das Handling während der Entwicklung deutlich komfortabler. Die ganzen Webfiles liegen einfach als normale Dateien im Projekt ohne etwas konvertieren oder Kompilieren zu müssen. Wenn man dann noch irgendein Webserver Plugin für seine IDE verwendet (z.B. Liveserver o.ä) kann man den ganzen Webcode sehr komfortabel entwickeln. Und wenn man fertig ist läd man nur die neuen Dateien hoch.
Das Problem an den ganzen Dateisystem Lösungen des ESP-IDF is, dass die alle globale Critical Sections haben. Sprich die würgen einfach mal so sämtliche User-Level Interrupts ab. Damit eignen sie sich nur für sehr zeitunkritische Anwendungen. Für die objcopy Variante bietet Espressif eine CMake Funktion namens "target_add_binary_data", siehe: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/index.html Das is zwar performanter, bringt aber eine ganz andere Reihe an Problemen mit sich... Ich selbst hab eine Web-Anwendung die ich via CMake auf einen ESP32S3 packe und dafür sind folgende Schritte notwendig: - Clonen des Releases - Ordner Struktur abflachen - gzippen aller Datein (optional) - Code Generierung eines constexpr LUT der die Datein in ihre ursprünglichen Pfade mapped Das is schon alles ziemlich PITA...
Flunder schrieb: > Ehrlich gesagt, habe ich mir dieses Filesystem im ESP32 noch nicht > angeschaut. Dann mach das mal. Flunder schrieb: > Bzw. kann ich den Bereich für das Filesystem auf nahezu null schrauben, > um den Platz dann für Daten, die sich in meinem Programmcode verstecken, > frei zu machen? In Arduino gibt's da Vorschläge für Partitionsschemata zur Auswahl über das Menü, z.B. huge_app.csv man kann aber auch eine custom partitions.csv im Sketch Ordner ablegen. https://github.com/espressif/arduino-esp32/tree/master/tools/partitions
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.