Forum: Mikrocontroller und Digitale Elektronik eeprom organisieren - wie macht ihr das?


von Peter S. (petershaw)


Lesenswert?

Hallo,
ich konsolidiere gerade Code und zerlege Programmteile, die ich in 
mehreren Projekten benötigt habe in einzelne abgeschlossene Teile und 
libs.
So ist ja schon meine crontab Implementierung herausgefallen: 
https://github.com/petershaw/AVR-Crontab

Bisher habe ich ohne Bootloader gearbeitet muss ich gestehen, aber mein 
neustes Projekt bekommt nur eine UART Schnittstelle und ich weiß das ich 
die firmware des öfteren updaten muss. Den Stein aus dem Board zu nehmen 
und zu flashen ist hier keine Option. Also Bootloader. Da gibt es je 
genug info hier im Forum.

Meine Idee - und Bestrebung der Konsolidierung - ist es einen Bootloader 
zu schreiben, der wieder für die meisten meiner Projekte taugt. Dafür 
muss er zwei Funktionen besitzen:
Firmware einspielen (check)
zugriff auf die System-Einstellungen geben, die ich (wie die meisten 
hier) im eeprom ablege.

Bisher ist mein eeprom ein wüster Sumpf aus gesetzten Bits an der 
richtigen Stelle. In der Firmware lege ich hart fest auf welcher 
Position welche Einstellung sitzt. Das ist zwar schön klein, aber 
unbrauchbar, wenn man abstrakter werden möchte.

Meine Frage an euch ist: wie organisiert ihr euren eeprom?

Ich habe da diese Idee, inspiriert von dem Solais BootProm 
(http://docs.oracle.com/cd/E19201-01/821-0901-10/OK_OBP.html) und denke 
darüber nach einen key/value store zu implementieren. In meinem 
Bootloader könnte ich dann mit
set KEY Value
get KEY
del KEY
die werte setzten. Dabei würde er am Ende einen serialisierten Sting in 
den eeprom schreiben, wobei booleans einfach als KEY-flag geschrieben 
werden und somit = true sind. ein false gibt es nicht, bzw der Flag 
taucht dann gar nicht auf.
eeprom: name:Struppi;kind=Dog;LCD_on;Debug
würde so zu der Tabelle:
name = Struppi
kind = Dog
LCD_on = true
Debug = true

im Bootloader könnte ich dann sagen
set Debug false
um das Flag zu entfernen.

Natürlich kann ich mir dann auch alles schön auflisten lassen.

Nach meinen Berechnungen komme ich mit meinen Gewöhnlichen Settings in 
1024 Byte bequem aus.

Was haltet ihr davon? Wie macht ihr das so?

Danke,
ps

von Organisator (Gast)


Lesenswert?

>Meine Frage an euch ist: wie organisiert ihr euren eeprom?

Mein letztes EEPROM habe ich von der Platine eines entsorgten Telefons 
abgelötet. Ist ein Atmel 24c32. Auf diese Weise habe ich bereits mehrere 
dutzend EEPROMs organisiert.

von Peter S. (petershaw)


Lesenswert?

Spasskeks.
ok, tittel kann man optimieren.

: Bearbeitet durch User
von SCNR (Gast)


Lesenswert?

Also ich organisiere meine eeproms i.d.R. von vorne hach hinten, ohne 
Lücken.  Also von Byte 0x00 aufwärts. Manchmal auch mit Lücken. Und 
gelegentlich lasse ich 0x00 weg.

von Hoppla ! (Gast)


Lesenswert?

Zuunterst (ab 0x0001) kommt immer die Geraetekennung, als ID und als 
String, dann kommt die Hardwareversion, dann die Firmwareversion. Und 
dann ist alles geraetespezifisch.

von petershaw (Gast)


Lesenswert?

Fliegenpilz schrieb im Beitrag #3348501:
> SCNR schrieb:
>> Also von Byte 0x00 aufwärts.
>
> Das ist schlecht. Fang bei 0x01 an, ichg sage dir, is besser so.

Das ist interessant. Warum soll man das so machen?

von Hannes L. (hannes)


Lesenswert?

petershaw schrieb:
> Warum soll man das so machen?

Weil einige ältere AVRs sich gern mal bei zu langsamem Abfallen der 
Versorgungsspannung den Inhalt der Zelle 0 zerschossen haben.

Bei moderneren AVRs und aktiviertem BOD ist das aber kein Problem mehr.

...

von Rangi J. (rangi)


Lesenswert?

Ich organisiere meine Daten nach Modulen, jedes Modul bekommt einen 
Block mit einer Base-Adresse, z.B. 0x0100, 0x0200, 0x0300 mit einer 
ungefähren Abschätzung wie gross Die Daten werden könnten. Das erste 
Byte in jedem Block ist die Version. Wenn sich das Moul ändert und neue 
oder andere Daten benötigt zähle ich die Version in der Software nach 
oben.
In der Init-Funktion des Moduls gibts dann eine switch(), die neue Daten 
an die entsprechende Stelle speichert (default-Wert setzen) oder ggf. 
Daten ändert. Diese switch kann man dann ohne breaks schreiben um 
Versionsupdates über mehrere Schritte auszuführen. Der case mit der 
aktuellen Version ist leer und 0xFF (EEProm leer) lädt alle 
Defaulteinstellungen.
Die Daten innerhalb des Bockes sind dann modulspezifisch und abhängig 
vom Entwicklungsablauf. Das Modul selber weiss nicht, wo seine Daten 
abgelegt sind, es muss nur ein Zeiger und Länge klarkommen. Dazu gibt es 
zwei Funktion "EEProm_SaveParams" und "EEProm_GetParams". Das 
EEProm-Modul weiss wiederum nichts vom Inhalt des Blockes.
Ich halte die Variante mit Strings ein bisschen zu groß. Der Vorteil, 
der sich durch die Verschiebbarkeit ergibt, wird durch den Overhaed an 
String-Parsing und lange Schreibzyklen negiert. Was passiert, wenn ein 
Parameter länger wird? Musst du dann alles folgende nach hinten 
kopieren? Du könntest deinen Key auch binär kodieren und eine wahlfreie 
Adresse dazu ablegen ala: "Gib mir Parameter 0815" oder "Speicher 
Paramter 0815". Die Nummern würde ich dann über ein globals enum 
realisieren. Als Sprungtabelle geht das einigermaßen fix.

von Peter D. (peda)


Lesenswert?

Peter Shaw schrieb:
> In der Firmware lege ich hart fest auf welcher
> Position welche Einstellung sitzt. Das ist zwar schön klein, aber
> unbrauchbar, wenn man abstrakter werden möchte.

Man kann sich auch überorganisieren.
Der EEPROM ist Privatsache der Applikation und interessiert den 
Bootloader nicht.
Falls der Bootloader selber was speichern muß (IP-Adresse), reserviert 
man ihm einen Bereich oder er speichert es in seinem Flash.

Für die Applikation nehme ich immer eine Struct im SRAM. Nach dem Reset 
wird sie aus dem EEPROM geladen bzw. auf Anforderung in den EEPROM 
gesichert.
Stimmt die CRC im EEPROM nicht, bleibt die Struct mit ihrer default 
Initialisierung geladen.

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

Peter Dannegger schrieb:
> Für die Applikation nehme ich immer eine Struct im SRAM. Nach dem Reset
> wird sie aus dem EEPROM geladen bzw. auf Anforderung in den EEPROM
> gesichert.
> Stimmt die CRC im EEPROM nicht, bleibt die Struct mit ihrer default
> Initialisierung geladen.

So ähnlich mache ich es auch. Nur habe ich am Anfang noch eine 
Versionsnummer mit drin. Beim Laden wird die geprüft und wenn sie 
kleiner ist als die aktuelle wird eine Update-Routine aufgerufen. Ist 
sie größer als die aktuelle, werden die Standardwerte belassen.

von petershaw (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Der EEPROM ist Privatsache der Applikation

Hallo Peter,

danke für deinen Beitrag!
Die Privatsache der Applikation ergibt sich aus der Betrachtungsweise wo 
ich das Level ansetze. Die Applikation kann auch der gesamte Chip sein, 
oder gar die Platine. In mach seltenen Fällen macht es vielleicht sogar 
sinn das fertige Gerät samt Umsysteme als Applikation zu sehen.
Sicherlich ist Dein Gedanke hier aber richtig. Laufen unterschiedliche 
firmwares auf dem Chip hat der bl nichts im eeprom verloren. Was aber 
wenn dieser dazu dient die fw upzudaten. Ich möchte in dem Falle ein 
neue Version aufspielen. Also das Verhalten der einen spezifischen App 
ändern, bzw fixen. Gehört dazu nicht auch, die Einstellungen 
(Preferences) updaten zu können.
Mein Ansatz ergibt sich aus der Überlegung das es manchmal rein über die 
Einstellung möglich ist ein Fix zu fahren. Also Softwarearchitekt lege 
ich das aber ungerne in die Firmeware, sondern eigentlich dahin wo ich 
auch die Updates einspielen kann: in den Bootloader.
Daraus ergibt sich der "Service.Modus"

Deine Anmerkungen hierzu interessieren mich sehr.

von Amateur (Gast)


Lesenswert?

Ich würde mich denen anschließen, die das EEPROM als guten Platz für 
eine Versions- und eventuell auch Unterversionskennung ansehen.
Ich würde noch etwas weiter gehen, und alles, was mit diesem Bereich 
zutun hat in eine eigene Datei (h/c) auszulagern.
Auf diese Weise sieht man gleich, wenn sich Inkonsistenzen durch neuere 
Anforderungen (Versionen) ergeben. Hier könnte dann auch die jeweils 
"Neue" Version ihre Anpassung an die Einstellungen aus einer alten 
Version vornehmen und sogar angepasste Meldungen, dann natürlich aus dem 
Flash, ausgeben.

von Peter D. (peda)


Lesenswert?

petershaw schrieb:
> Deine Anmerkungen hierzu interessieren mich sehr.

Die Frage ist, soll es ein allgemeiner Bootloader werden oder einer nur 
speziell für dieses Projekt.

Ich habe auch einige Projekte, wo im EEPROM ein kleiner Bereich für den 
Bootloader reserviert ist. Darin kann man z.B. einmalig den Gerätetyp 
eintragen und so verhindern, daß eine falsche Firmware programmiert 
wird. Dieser Bereich sollte für die Applikation nicht schreibbar sein.

Soll die Applikation Settings empfangen können, so hat sie ihre eigenen 
Routinen dafür.
Bootloader und Applikation benutzen also keinen Code oder EEPROM 
gemeinsam.

Die Applikation kann über ein Watchdogreset den Bootloader starten und 
damit das Update einleiten.

: Bearbeitet durch User
von Rangi J. (rangi)


Lesenswert?

Schreib dir doch einen allgemeinen Bootloader. Der kann dann zb. 
S19-Zeilen intepretieren und flashen. Zusätlich denkst du dir in diesem 
Format einfach noch weitere Zeilen aus, die im Standard nicht vorkommen 
und belegt sie mit so Funktionen wie EEPROM beschreiben, EEPROM 
umkopieren, EEPROM löschen.
Jetzt musst du beim Software (make-file) bauen an den S19-File noch 
weitere eigen Zeilen anhängen, die das machen, was du willst. Die 
Software des Bootloaders auf PC-Seite muss dann nichts von deinen 
Änderungen wissen und überträgt einfach nur die Zeilen.
So kann man z.b. auch ein Software-Download in Shadow mit späterem 
Umkopieren realisieren.

von Peter S. (petershaw)


Lesenswert?

Hallo Jungs,

das sind alles sehr interessante Gesichtspunkte und haben mich ein 
entscheidenden Schritt in meiner Planung weitergebracht. Mein 
Ursprüngliches Modell muss ich definitiv Überdehnen  und gehe erstmal 
zurück ans Whiteboard.
Es bleibt jedoch bei einem gewünschten "God"-Mode. hier muss ich 
Settings und Firmaware aus einer "Shell" bedienen können. Werte 
lesen/setzen, flashen.... Ob ich das als Makefile mache und eine 
Software anbiete, oder über eine Terminal-Lösung implementiere die auf 
der Bootloader oder Softwareseite aufsetzt (ev. lib, die eingebunden 
sein muss) plane ich momentan neu.
Thema ist, das verschiedene Customized Software stände auf den Chips 
laufen werden und ich sicher gehen möchte im Wartungsbetrieb nicht auf 
eine große Liste an unterschieden in der Software reagieren zu müssen.

..tbd.

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
Noch kein Account? Hier anmelden.