Hallo,
ich suche nach einer "kleinen" open-source Library, die es ermöglicht,
Config-Dateien (Format richtet sich nach Lib) einzulesen.
Auf dem Rechner habe ich immer gerne libconfig verwendet. Das ist recht
simpel und angenehm (https://github.com/hyperrealm/libconfig).
Allerdings erfüllt diese Lib für mein aktuelles Programm die
Anforderungen nicht ganz:
Es handelt sich um ein embedded Projekt auf einem STM32F4. Somit sind
Programmspeicher und RAM zumindest recht endlich.
Mein Controller hat 512 kB Flash und ist momentan zu ca 30 % voll. Grob
geschätzt wird mein Code, wenn er fertig ist, den Controller zu 50 - 60
auslasten. Die Library sollte somit in den verbleibenden Speicher passen
~200 kB.
libconfig gefällt mir in diesem Fall nicht so, da sie dynamischen
Speicher benötigt. Meine Software kommt bisher ohne Heap aus und ich
fände es schön, wenn das auch so bleibt.
Das Format der Configdateien, die zu lesen sind, ist mir quasi egal. Es
muss lediglich von Hand editierbar sein (ASCII Klartext) und die
Möglichkeit bieten
'key = value' Paare abzubilden.
Nochmal die Anforderungen in Stichpunkten:
1) Wenn möglich: Statischer Speicherverbrauch!
2) In C geschrieben
3) Open Source (verwendbar in einem GPLv2 Projekt)
4) Akzeptabler Footprint für embedded SW
Vielen Dank
Mal eine ernst gemeinte Frage: Was ist daran schwer, ein Properties File
zu parsen? Dafür braucht man doch keine Library!
Alles, was man dazu braucht, befindet sich in der stdio.h und string.h.
Stefan ⛄ F. schrieb:> Mal eine ernst gemeinte Frage: Was ist daran schwer, ein Properties File> zu parsen? Dafür braucht man doch keine Library!>> Alles, was man dazu braucht, befindet sich in der stdio.h und string.h.
Ansich nichts. Für meine Anforderungen reicht das auch. Ich bin aber
neugierig, was es für embedded-geeignete Libraries gibt, die vielleicht
noch etwas mehr können. Eventuell auch für zukünftige Projekte. Aus
eigener Erfahrung weiß ich, dass ein guter Parser gar nicht so leicht
ist, wenn er robust sein soll.
M. H. schrieb:> Aus eigener Erfahrung weiß ich, dass ein guter Parser gar> nicht so leicht ist, wenn er robust sein soll.
Ja aber es geht doch um ein Embedded Projekt, nicht um einen Web Browser
der alles schlucken können muss, was da kommen mag.
Stefan ⛄ F. schrieb:> Ja aber es geht doch um ein Embedded Projekt, nicht um einen Web Browser> der alles schlucken können muss, was da kommen mag.
Das schon. Aber IMHO ist es einfach blöd, wenn der Parser sich bei
irgendwas verspult und dann Murks macht. Auch auf in einem embedded
Projekt. Deswegen, ja die Frage nach erprobten Lösungen. Wenn sich
nichts findet, kann ich den Parser ja immernoch selbst schreiben.
Stefan ⛄ F. schrieb:> Mal eine ernst gemeinte Frage: Was ist daran schwer, ein Properties File> zu parsen? Dafür braucht man doch keine Library!
Wer sagt, dass es schwer ist? Aber wozu das Rad neu erfinden, wenn's
schon eins gibt?
Warum muss man configs ASCII kodiert speichern? Das ist ja wohl die
größte Platzverschwendung.
Bau dir nen Struct (ggf. mit Unions) der alles enthält und schieb/les
den nach/von wo auch immer.
Kevin M. schrieb:> Warum muss man configs ASCII kodiert speichern? Das ist ja wohl die> größte Platzverschwendung.
Weil ich die Files gerne manuell bearbeiten können würde. Und structs
sind einfach zu anfällig für architektur-/implementierungs-spezifische
Fallstricke (endianess, packing, etc...)
Ich habe alles auf Json umgestellt.
Ist einfach, und struktutiert. Ich kann es beliebig erweitern, falls ein
Attribut fehlt.
Und es gibt im Web Seiten mit Syntax-Checker, falls man sich nicht
sicher ist.
Nie wieder eigene Ascii-Formate. Das führt nur zu Problemen, wenn es
erweitert werden soll.
ASCII wie das .ini Format kann man ja noch erweitern, aber es hat keine
Baumstruktur was bei Json noch schöner ist. Beim Binärformat opfert man
alles der Performance, was bei halbwegs modernen μC kaum noch nötig ist.
Ein schlanker Json Parser ist JSMN, https://github.com/zserge/jsmn
Wie bringst Du den die Konfigurationsdatei auf das Target? Wenn dass
während der Build-Zeit passiert, dann ist das Parsen der Datei zur
Laufzeit ziemlicher Overhead, da sich die Parameter ja zur Laufzeit
nicht ändern.
ECUs in Autos haben relativ viele Parameters. Das wird mit Diagnose
(UDS) gelesen oder geschrieben (Bonus ist heute: Sichere Fahzeug
Diagnose SFD also man muss sich das per Hersteller auch erlauben
lassen). Meist wird das Lesen/Schreiben per DID verwendet. Ab und zu mal
Routine Controlle (ist aber selten). Gespeichert wird das ganze in
Eeprom. Natürlich wird hier nicht einfach gespeichert, sondern ein
Datensatz abgelegt mit eventuell redundanz in ein Journaling System. So
weit eigentlich einfach. Aber, damit man einfach mehrere tausend
Parametern haben kann, gibt es natürlich ein Generator der die
Konfiguration für die Diagnose und Eeprom generiert. Plus das ganze
Verbindet und die Paramters richtung Applikation bereitstellt. So kann
jemand in einer Excel Tabelle oder DOORS oder oder oder die Parameters
erstellen, und das ganze Zeug wird dann generiert. Kann man schön unter
dem Stichwort: AUTOSAR nachschauen
Und das passt noch in einen Cortex-M? Werden da nicht eher -A/R
verwendet?
Das vorher vorgeschlagene cJSON gefällt mir auch, kann schon etwas mehr
als JSMN.
200kByte fuer ein Konfig library... uups.
Wer redet denn von ASCII Formaten? Die wuerde ich mir eh nicht antun.
Ich wuerde mit auch generell nicht lesbare ACII Formate fuer embedded
antun.
Allenfalls als csv. Da kommt man mit einem 20 Zeiler durch.
> Ein Menüsystem kostet teilweise deutlich mehr.
Also ich finde diese 200k schon voellig ueberzogen. Ein Menusystem soll
groesser sein ? Das waer dann nicht mehr meine Welt.Bei mir muss alles
viel kompakter sein. Ohne 3D Simulationen auf dem Display.
Joggel E. schrieb:> Ohne 3D Simulationen auf dem Display.
Eine einzelne Schriftart, 30 px hoch ("A-Höhe"), Zeichen ' ' bis 255,
sind selbst RLE-codiert schon 8,8 kb. Ohne Sonderzeichen für
physikalische Größen etc. Kann schon sein, dass das nicht Deine Welt
ist. Aber Seltenheitswert hat es auch nicht mehr.
Aber der TO hat das ja auch klar als Maximalgröße benannt.
PittyJ schrieb:> Ich habe alles auf Json umgestellt.> Ist einfach, und struktutiert. Ich kann es beliebig erweitern, falls ein> Attribut fehlt.> Und es gibt im Web Seiten mit Syntax-Checker, falls man sich nicht> sicher ist.
Ja das JSON-Format ist schon nicht schlecht, weil es auch für den
Menschen lesbar ist. Allerdings ist der Aufwand zum Lesen und Schreiben
schon deutlich größer als z.B. bei einer einfachen Liste mit
Wertepaaren.
Schau Dir einfach mal die JSON-Daten des Deutschen Wetterdienstes
(https://opendata.dwd.de/weather/weather_reports/synoptic/germany/json/)
an. Diese Files sind schon sehr komplex und da hat ein JSON-Parser auf
dem PC schon ordentlich zu tun um Selbige zu dekodieren. Ein µC wäre an
dieser Stelle wahrscheinlich schon überfordert. Andererseits ist ein
Konfigurationsfile für einen µC deutlich einfacher als die von mir als
Beispiel genannten Files.
Eine einfache Liste mit Wertepaaren Key=Value halte ich auf dem µC für
den einfacheren Weg, die mit Mitteln die Standard C bietet auch leicht
einzulesen und zu dekodieren ist - Stefan schrieb das ja auch schon. So
groß werden die Listen ja auch nicht werden, da die Anzahl der Parameter
ja eher klein und überschaubar ist.
Ich benutze dieses Format gern für Konfigurationsdateien in meinen
PC-Programmen. Das Format entspricht ja wenn man noch Sections einführt
dem Windows-Iniformat, wofür es in vielen Programmiersprachen bereits
fertige Klassen zum Lesen und Schreiben gibt. Anderseits kann man unter
Delphi die komplette Datei in eine Stringliste einlesen, welche ein
Property Values[Key] hat so das man den Wert ganz gezielt auslesen kann.
Hat man weder eine Klasse noch dieses Listenobjekt kann man eine solche
Datei auch einfach Zeile für Zeile einlesen und auswerten. Dafür braucht
man definitiv keine Lib, die bringt viel zu viel Overhead mit.
Torsten R. schrieb:> Wie bringst Du den die Konfigurationsdatei auf das Target?
SD Karte oder TFTP.
kyrk.5 schrieb:> AUTOSAR nachschauen
Als nächstes schlägst du mir noch vor, dass ich mir zum Einspieln der
Config eine ETAS INCA Lizenz kaufen soll ;)
Johannes S. schrieb:> Ein schlanker Json Parser ist JSMN, https://github.com/zserge/jsmn
Das sieht schonmal recht gut aus. Das kommt auf die Liste. Vielen Dank.
Johannes S. schrieb:> cJSON gefällt mir auch, kann schon etwas mehr> als JSMN.
Benötigt allerdings dynamischen Speicher. Mal schauen. Ich werde mal
evaluieren, wie viel das ist und ob es memory-leak frei ist :)
Joggel E. schrieb:> 200kByte fuer ein Konfig library... uups.
Ich sage nicht, dass ich das auch vollkriegen will. Man muss allerdings
beachten, dass bei einem cortex-M der Speicher schneller ansteigt, als
bei einem AVR. Da sind allein für den Startupcode schonmal ruckzuck
1-2kB weg.
Ich denke, ich werde mir die JSON Lösungen mal anschauen.
Bei einer String basierten Config wird man um Dynamik nicht drumherum
kommen wenn man die Config auf dem µC auch ändern möchte. Wenn du z.B.
einen vorhandenen String Wert änderst und der neue ist ein paar Zeichen
länger, dann muss man den alten Teil ja wegwerfen und einen neuen Knoten
erzeugen und einbinden. Alles mit vordefinierten Reserven und Limits
wäre vielleicht eine Lösung, ist aber auch Verschwendung wenn diese
Reserven nie gebraucht werden. Wenn die Config nur gelesen und nicht
verändert wird, dann dürfte man auch nicht in eine Dynamik reinlaufen.
Von cJSON gibt es noch eine C++ Version, die versuche ich gerade zu
kompilieren. Leider hat der Autor da vor ein paar Tagen die sstream
eingebaut... Aber du wolltest ja sowieso kein C++.
Hm..
wie wäre es denn wenn Du Dir die config sparst
und sie stattdessen als ini betrachtest?
damit wären die Variablen schon im µC gesetzt und korrekt dimensioniert
und die ini file überschreibt nurnoch die default-werte wo nötig.
der parser dazu wäre nichteinmal wirklich gross;
da er unbekannte oder unzulässige werte schlicht ignorieren könnte.
bei feststehendem Code machen inis fast immer mehr Sinn mMn;
da man selten nicht definierte aber benötigte Variablen/Werte nicht
irgendwo vordefiniert hat,
nur den Wert nicht den typ zu wechseln ist da relativ simple über inis
zu regeln.
'sid
M. H. schrieb:> Das Format der Configdateien, die zu lesen sind, ist mir quasi egal. Es> muss lediglich von Hand editierbar sein (ASCII Klartext) und die> Möglichkeit bieten> 'key = value' Paare abzubilden.
Warum muß man da gleich mit einer riesen Dampfhammer Lib draufschlagen?
Ein simples sscanf über ein Array aus String+Variablenadresse sollte
doch reichen.
Und noch ein Zeichen als Kommentarzeile festlegen, um Parameter temporär
zu disablen. Das Arrayende kennzeichne ich immer mit einem Leerstring,
dann muß man nicht extra die Länge übergeben.
Die Textdatei parst man direkt beim Einlesen, man braucht also nur
temporären RAM für eine Zeile (80 Byte, alles darüber wird
abgeschnitten). Das Array steht im Flash, kostet also weder statischen
RAM noch Malloc.
Als ich das letzte mal sowas gebraucht habe, da habe ich mir
das in flex geschrieben und dann den erzeugten C-Code in mein
Programm eingehaengt. Das ist super weil man sich jederzeit neue
coole Schluesselwoerter einfallen lassen kann und sich dann einfach
einen neuen Parser generiert.
Vorteil ist das flex auf jedem ernst zunehmenden Betriebssystem bereits
installiert ist. Geht also einfach so.
Olaf
M. H. schrieb:> Auf dem Rechner habe ich immer gerne libconfig verwendet. Das ist recht> simpel und angenehm (https://github.com/hyperrealm/libconfig).> Allerdings erfüllt diese Lib für mein aktuelles Programm die> Anforderungen nicht ganz:>> Mein Controller hat 512 kB Flash und ist momentan zu ca 30 % voll. Grob> geschätzt wird mein Code, wenn er fertig ist, den Controller zu 50 - 60> auslasten. Die Library sollte somit in den verbleibenden Speicher passen> ~200 kB.
libconfig hat bei mir für Cortex-M4 compiliert ~14kB
arm-none-eabi-size armv7e-m/lib/libconfig.a
text data bss dec hex filename
1896 0 0 1896 768 grammar.o (ex
armv7e-m/lib/libconfig.a)
3643 0 0 3643 e3b libconfig.o (ex
armv7e-m/lib/libconfig.a)
435 0 0 435 1b3 scanctx.o (ex
armv7e-m/lib/libconfig.a)
7962 0 0 7962 1f1a scanner.o (ex
armv7e-m/lib/libconfig.a)
78 0 0 78 4e strbuf.o (ex
armv7e-m/lib/libconfig.a)
Bleibt das Problem mit dem dynamischen Speicher. Wenn du da aber nicht
ständig neu einliest sondern z.B. nur einmalig beim start sehe ich da
auch kein Problem.
Bisschen blöd ist die Lizenz (LGPL). Das verhindert bei uns den Einsatz
auf Cortex-M.
Matthias
Μαtthias W. schrieb:> Bisschen blöd ist die Lizenz (LGPL). Das verhindert bei uns den Einsatz> auf Cortex-M.
Erkläre mal, ich erkenne da keinen Zusammenhang zwischen LGPL und
Cortex-M. Habe ich etwas verpasst?
Stefan ⛄ F. schrieb:> Μαtthias W. schrieb:>> Bisschen blöd ist die Lizenz (LGPL). Das verhindert bei uns den Einsatz>> auf Cortex-M.>> Erkläre mal, ich erkenne da keinen Zusammenhang zwischen LGPL und> Cortex-M. Habe ich etwas verpasst?
Ist halt mitunter etwas unschön, die Hard- und Firmware so weitergeben
zu müssen, dass der Anwender die Möglichkeit hat, die LGPL-Komponenten
durch selbst compilerte zu ersetzen.
Wenn die config so übermäßig kompliziert ist, dann schreib dir doch ein
command line tool für den Rechner (ggf. mit beliebiger lib dahinter),
das eine ASCII config einliest und in binär (unions, structs) übersetzt
(oder binär in den Target-µC läd). Dadurch verschwendest du nicht so
viel Platz und Zeit im µC und bist flexibel in der Wahl deiner lib.
Sonne schrieb:> Wenn die config so übermäßig kompliziert ist,
Das ist ja eben der Witz, er will nur was ganz einfaches:
M. H. schrieb:> 'key = value' Paare abzubilden.
Ich würde dafür 10 Zeilen und 10min ansetzen. Aber er will ja unbedingt
mit Kanonen auf Spatzen schießen.
Olaf schrieb:> Als ich das letzte mal sowas gebraucht habe, da habe ich mir> das in flex geschrieben und dann den erzeugten C-Code in mein> Programm eingehaengt. Das ist super weil man sich jederzeit neue> coole Schluesselwoerter einfallen lassen kann und sich dann einfach> einen neuen Parser generiert.> Vorteil ist das flex auf jedem ernst zunehmenden Betriebssystem bereits> installiert ist. Geht also einfach so.
Daran habe ich auch schon gedacht. Allerdings benötigt (f)lex auch
dynamischen Speicher. Flex würde ich nur verwenden, wenn ich, wie du
sagst, eigene Schlüsselwörter etc. benötige.
Μαtthias W. schrieb:> libconfig hat bei mir für Cortex-M4 compiliert ~14kB
Das sieht ja gar nicht mal so schlecht aus. Hat eventuell schonmal einer
nen Leaktest mit libconfig gemacht, ob das Ganze speicher verliert?
Ich bin mittlerweile sehr vorsichtig geworden. Die letzte PC
Applikation, die ich geschrieben habe, hatte so viele memory Leaks in
extern verwendeten Libraries, dass ich teilweise dazu übergehen musste,
Teile des Programms über Forking in extra Prozesse zu verlagern, um die
Prozesse dann sauber wieder beenden zu können, damit der Speicher nicht
vollläuft. Und auf embedded Geräten ist ein schleichend wachsender Heap
recht schnell am Anschlag.
Peter D. schrieb:> Das ist ja eben der Witz, er will nur was ganz einfaches...
.. und dafür setzt er rund 200K an. Erstmal. Ich tippe da auf die
bekannte Salami-Taktik: immer scheibchenweise.
Man fragt sich, was das eigentlich werden soll. Ich bin bei meinen
Geräten bislang immer mit üblichen seriellen EEPROMs ausgekommen, da
kriegt man eine stattliche Anzahl von Einstell-Flags,
Kalibrierkonstanten und sonstiges Zeugs unter.
Möglicherweise ist das Ganze beim TO ein Denkfehler, nämlich daß er ein
Menüsystem in diversen Sprachen haben will und daß er dieses genauso wie
beim PC beim Programmstart aus einer Art Ressourcen-Datei in den RAM
laden will. Der Denkfehler in diesem Falle ist, daß man im µC auch
grafische Menüsystem mit Touch-Bedienung und in C geschrieben im Flash
unterbringen kann. Sowas ist dann bereits beim Einschalten fertig
miteinander verknüpft und das Initialisieren besteht bloß darin, daß ein
jegliches Objekt des Menüs seine Variablen initialisiert. Texte hingegen
macht man dann per Handle und läßt sich die Pointer auf die zugehörigen
Strings von einer Funktion liefern, die den jeweiligen Text in der
aktuellen Sprache liefert. Und sowas ist sehr viel platzsparender als
200K an zu interpretierenden Konfig-Texten.
W.S.
W.S. schrieb:> Möglicherweise ist das Ganze beim TO ein Denkfehler, nämlich daß er ein> Menüsystem in diversen Sprachen haben will und daß er dieses genauso wie> beim PC beim Programmstart aus einer Art Ressourcen-Datei in den RAM> laden will
Ich lese nichts derartiges in der Frage des TO. Eventuell ist die
Antwort auf einen anderen Thread bezogen?
Ich lese aus der Frage lediglich: "Ich suche X, habe noch viel Flash
(200 kb) frei, Verzicht auf malloc() wäre bevorzugt."
M. H. schrieb:> Aber IMHO ist es einfach blöd, wenn der Parser sich bei> irgendwas verspult und dann Murks macht.
Genau das kann aber passieren, wenn man sich den maximal möglichen
Overhead ans Bein bindet.
Eine riesen Lib kann durchaus fehlerfrei sein, aber man kann Fehler bei
der Anwendung machen, weil man sie nicht in allen Details verstanden
hat. Den Murks hat man dann selbst erzeugt.
Es ist gar nicht so einfach, eine Lib so zu schreiben, daß sie alle
Anwenderfehler abfängt.
Je einfacher die Aufgabe, umso weniger lohnt sich die Einarbeitung in
eine unbekannte Lib. Eine Lib soll ja Entwicklungszeit sparen und nicht
kosten.
M. H. schrieb:> Μαtthias W. schrieb:>> libconfig hat bei mir für Cortex-M4 compiliert ~14kB>> Das sieht ja gar nicht mal so schlecht aus. Hat eventuell schonmal einer> nen Leaktest mit libconfig gemacht, ob das Ganze speicher verliert?
Ja, libconfig läuft bei uns in unittests mit die mit valgrind (GCC) bzw.
asan (clang) compiliert sind. Bisher keine Auffälligkeiten.
Matthias
W.S. schrieb:> .. und dafür setzt er rund 200K an. Erstmal. Ich tippe da auf die> bekannte Salami-Taktik: immer scheibchenweise.
Ich finde das um ehrlich zu sein mittlerweile eine Frechheit hier: In
allen Threads wird sich beschwert, dass der TO nicht mit den
Infrormationen rausrückt. Ich habe hier gedacht: "Schreib halt hin wie
viel du Platz hast, bevor einer erst fragen muss, wie viel Flash dafür
da ist". Ich setze dafür keinesfalls 200k an. Das ist eben das, was ich
noch zur Verfügung habe.
W.S. schrieb:> Möglicherweise ist das Ganze beim TO ein Denkfehler, nämlich daß er ein> Menüsystem in diversen Sprachen haben will und daß er dieses genauso wie> beim PC beim Programmstart aus einer Art Ressourcen-Datei in den RAM> laden will. Der Denkfehler in diesem Falle ist, daß man im µC auch> grafische Menüsystem mit Touch-Bedienung und in C geschrieben im Flash> unterbringen kann. Sowas ist dann bereits beim Einschalten fertig> miteinander verknüpft und das Initialisieren besteht bloß darin, daß ein> jegliches Objekt des Menüs seine Variablen initialisiert. Texte hingegen> macht man dann per Handle und läßt sich die Pointer auf die zugehörigen> Strings von einer Funktion liefern, die den jeweiligen Text in der> aktuellen Sprache liefert. Und sowas ist sehr viel platzsparender als> 200K an zu interpretierenden Konfig-Texten.
Ähm... nein. Und falls es dich interssiert: Das Menusystem ist recht
schlank, da 4x16 Character LCD ohne groß verschachtelte Menüs.
W.S. schrieb:> Man fragt sich, was das eigentlich werden soll. Ich bin bei meinen> Geräten bislang immer mit üblichen seriellen EEPROMs ausgekommen, da> kriegt man eine stattliche Anzahl von Einstell-Flags,> Kalibrierkonstanten und sonstiges Zeugs unter.
Das habe ich leider beim Platinendesign verpeilt. Und der STM hat leider
kein internes EEPROM. Und die Flashpage möchte ich nicht dafür
freihalten. Das ist einfach bissle doof gelaufen. Deswegen kommen die
Parameter auf die SD Karte.
Was es wird: Es lädt Regelparameter für einige Regler. Insgesamt so ca.
56 Parameter + Eine Lookup Tabelle mit grob 1k Größe. ISt aber für diese
Diskussion irrelevant.
Μαtthias W. schrieb:> Ja, libconfig läuft bei uns in unittests mit die mit valgrind (GCC) bzw.> asan (clang) compiliert sind. Bisher keine Auffälligkeiten.
Sehr schön. Vielen Dank für die Info.
Prinzipiell habe ich hioer im Forum nachgefragt, da ich nicht davon
ausgehe immer alles besser coden zu können als andere und vielleicht
hätte es ja "den Standard" für sowas gegeben. Alles in allem sind aber
doch ein paar interessante Links rausgesprungen. Am Wochenende komme ich
je nach Wetterlage dazu, weiterzubasteln.
@bambel:
W.S. ist hier einer der übleren Schwätzer der so tut als wär er der
Größte aber dan Code mit Magic Numbers, sinnlosen Dopplungen und gotos
verzapft.
Was "const" in C ist weis er auch nicht.
Reinstes Comedygold zum lesen:
Beitrag "Re: C: Konstante weak definieren"
M. H. schrieb:> Und der STM hat leider> kein internes EEPROM. Und die Flashpage möchte ich nicht dafür> freihalten. Das ist einfach bissle doof gelaufen.
Da du ja eh so viel Flash übrig hast, warum nicht den benutzen, schau
dir mal die EEPROM-emulation Beispiele von ST an. Da kannst du (wenn es
nicht super Zeitkritik ist) ganz einfach key (16 bit) value (16bit)
Paare ablegen. muss halt 2 Flashpages für spendieren.
Das hat aber erst mal nichts mit einer Config Datei zu tun
M. H. schrieb:> Das habe ich leider beim Platinendesign verpeilt. Und der STM hat leider> kein internes EEPROM. Und die Flashpage möchte ich nicht dafür> freihalten. Das ist einfach bissle doof gelaufen. Deswegen kommen die> Parameter auf die SD Karte.> Was es wird: Es lädt Regelparameter für einige Regler. Insgesamt so ca.> 56 Parameter + Eine Lookup Tabelle mit grob 1k Größe. ISt aber für diese> Diskussion irrelevant.
Bist du dir sicher, daß du SO ETWAS tatsächlich tun willst? Ich nehme
mal an, daß deine 'einige' Regler irgend etwas Wichtiges regeln. Und da
willst du deren Parameter auf einer SD speichern? Mir wäre das viel zu
unsicher, die Parameter würde ich auf alle Fälle mit in die Firmware
integrieren - oder jedenfalls deren Default-Werte, die aber regelseitig
auf der sicheren Seite liegen müssen.
W.S.
Peter D. schrieb:> Je einfacher die Aufgabe, umso weniger lohnt sich die Einarbeitung in> eine unbekannte Lib. Eine Lib soll ja Entwicklungszeit sparen und nicht> kosten.
Prinzipiell gebe ich dir da recht aber ich finde gerade die hier
genannte Library doch sehr schlank und bis auf die #ifdef-Orgien (die
der Wahl zwischen Stack und Heap geschuldet sind) auch durchaus elegant
geschrieben.
Richard Z. schrieb:> Ich verwende in der Kombination "Microcontroller/SD-Karte" eigentlich> immer:> https://github.com/benhoyt/inih
W.S. schrieb:> Bist du dir sicher, daß du SO ETWAS tatsächlich tun willst? Ich nehme> mal an, daß deine 'einige' Regler irgend etwas Wichtiges regeln. Und da> willst du deren Parameter auf einer SD speichern?
Ja ich bin mir sicher! Per default macht das Gerät gar nichts, da es
keine universal gültigen Regelparameter gibt. Diese müssen über eine
UART Shell und einige Abgleichalgorithmen erst für jedes System gefunden
werden. Sind diese gefunden, werden sie auf SD-Karte gespeichert und von
dort auch beim Neustart wieder geladen. In der nächsten Version (falls
sie jemals kommt) kommt dann entweder ein SPI EEPROM dran, oder der STM
bekommt eine Backupbaterie für den Backupram.
M. H. schrieb:> In der nächsten Version (falls sie jemals kommt) kommt dann entweder ein> SPI EEPROM dran, oder der STM bekommt eine Backupbaterie für den> Backupram.
Ich würde die Idee mit dem emulierten EEPROM durch den Flash nicht so
schnell verwerfen. Das ist ja schließlich kein NAND-, sondern NOR-Flash
und wenn ich mich recht erinnere garantiert ST 10k Schreibzyklen
innerhalb des erlaubten Temperaturbereichs, was dann bei
Zimmertemperatur nochmal deutlich mehr sein dürfte. Eine SD-Karte ist
zwar günstig in der Beschaffung und bietet massig Speicher aber für die
paar Parameter würde ich mir die Abhängigkeit von der SD-Karte glaube
eher nicht ans Bein binden.
Christopher J. schrieb:> Ich würde die Idee mit dem emulierten EEPROM durch den Flash nicht so> schnell verwerfen. Das ist ja schließlich kein NAND-, sondern NOR-Flash
Darum geht es mir gar nicht. Mir geht es darum, dass der Flash nicht wie
ein EEPROM geschrieben werden kann, sondern nur Pageweise gelöscht
werden kann. Und die Pagegrößen des STMs sind eher unpraktisch dafür.
Vorallem die hinteren Pages, die ich dafür gern verwendet hätte, sind
128kB groß. Und das ist mir einfach zu viel Speicher, den ich Freihalten
müsste.
Um was für ein STM32F handelt es sich denn, ich kenne keinen mit so
großen Pages (eigentlich nur 1k oder 2k), und ob die Konfigdaten vorne
oder hinten liegen spielt doch gar keine Rolle.
Die EEPROM Emulation ist imho wirklich gut ausgeklügelt, und fängt auch
reset währen des Schreibprozesses usw ab. und du kannst einfach
Paarweise Key:Value schreiben und auslesen, also wirklich einfach zu
verwenden.
Wenn ich es richtig verstehe willst du aber nur einmalig Konfig Daten
schreiben, da kannst du dir das auch ganz sparen und einfach so in den
Flash schreiben, das muss nicht pageweise passieren, nur eine Änderung
bedingt das die Page zuvor komplett gelöscht werden muss.
nurmal so schrieb:> Um was für ein STM32F handelt es sich denn, ich kenne keinen mit so> großen Pages (eigentlich nur 1k oder 2k), und ob die Konfigdaten vorne> oder hinten liegen spielt doch gar keine Rolle.
Die "hinteren" Sektoren der STM32F4 haben laut Reference Manual immer
128k.
Aber normalerweise sollte man die App ja ohne Probleme weiter nach
hinten schieben und dann die Pages 1 und 2 die jeweils 16k haben für die
Daten verwenden können.
Da Pagegröße hängt stark von der Serie ab.
L4 haben schöne 2k Pages (auch da gibts sicher Ausnahmen die ich nicht
gesehen habe).
Bei den F4 sind die Pagegrößen wild verteilt von ein paar k bis 128k
hoch, das ist für eine EEPROM Simu im Flash natürlich etwas blöd.
Die kleinen L0 haben sogar nur 256?Byte große Pages.
Ansonsten gibts von ST selber ne Appnote zu dem Thema:
https://www.st.com/resource/en/application_note/dm00311483-eeprom-emulation-techniques-and-software-for-stm32-microcontrollers-stmicroelectronics.pdf
Mit dieser Appnote habe ich eine "Tag Length Value" Configspeicherung im
Flash gebaut für L4 inkl. "RAID1" falls beim schreiben/page löschen mal
der Strom verschwindet und somit die Config nicht inkonsistent wird.
Mw E. schrieb:> Bei den F4 sind die Pagegrößen wild verteilt von ein paar k bis 128k> hoch, das ist für eine EEPROM Simu im Flash natürlich etwas blöd
Als flashes noch extern waren, und 64k eine Page, da würde viel Aufwand
getrieben um eine Page in 16, 8, 8 und 32 zu teilen:
Einem loader/bootet in den 16k und dann 2 8k-Bereiche, um Bootinfos
schreiben zu können. Z.b. jeweils 1k Felder mit den Segmenten, Version,
Checksumme etc. Beim nächsten Booten altes Feld ungültig und nächste 1k
beschreiben. War ein Block voll, den anderen nehmen und den einen
löschen.
Und weil es genau dafür gemacht wurde, könnte man z.b. den 16k Block
schreibschützen und die 8ks offen lassen.
Und weil der Resetvektor manchmal ganz oben, manchmal unten war, gab es
2 sonst identische Typen.
Will sagen, wild verteilt ist eher unwahrscheinlich....
Es ist immer gut dazu zu lernen.
Bei den ext. (Q)SPI NOR Flashes die ich so kenne gibts 4k Pages.
Aber auch löschbare Blöcke, die dann 32k/64k haben und dann mehrere der
4k Pages entahlten.
Daher sieht das beim F4 erstmal wild aus und beim L4 ist es eben schöner
gelöst.