Forum: Compiler & IDEs EEPROM: Ende des statisch reservierten Bereichs ermitteln?


von Thomas M. (langhaarrocker)


Lesenswert?

Hi
Ich möchte im EEPROM nicht nur Daten mit statischer Größe, sondern 
zusätzlich auch eine Datenstruktur speichern, deren Größe erst zur 
Laufzeit bekannt wird. Damit die dynamische Datenstruktur nichts 
überschreibt, darf sie natürlich erst hinter dem reservierten Bereich 
abgelegt werden.
Ich finde jedoch keine Möglichkeit das Ende des reservierten Bereichs 
(EEMEM) zu ermitteln.

Zur Zeit behelfe ich mir damit in einem struct alle EEPROM Daten fixer 
Größe zusammenzufassen. So kann ich mittels sizeof die Größe berechnen 
lassen und als Offset verwenden. Dieser Ansatz ist jedoch eigentlich 
Schrott, da dadurch die Modularität der Software im Eimer ist.

Wie löst Ihr sowas?

von Le X. (lex_91)


Lesenswert?

Hi,

das ist ein guter Punkt den du da ansprichst.
Auch ich organisier mein EEPROM als große Datenstruktur. Über Makros 
kann man sich recht bequem die Adressen der einzelnen Member liefern 
lassen.

Natürlich muss dazu jedes Modul diese Datenstruktur kennen.
Dadurch könnte ein Modul theoretisch auch auf Member zugreifen, die sie 
nichts angehen. Das ist ein Problem, ja.
Allerdings ist das bei EEPROM eh so ne Sache. Theoretisch kannst du ja 
direkt auf jede Adresse zugreifen.

Aber die Modularität geht eigentlich nicht verloren. Ändert sich die 
Zusammensetzung oder Aufbau der Struktur liefert das Makro eben ne 
andere Adresse, das stört ja das Modul nicht (einen Mechanismus zur 
Erkennung von ungültigen Werten, z.B. durch Checksumme, vorausgesetzt).

Ganz im Gegenteil, ohne diese Struktur geht dir Modularität verloren.
Dann müsstest du doch in jedem Modul entscheiden, an welche Stelle des 
EEPROM du nichtflüchtige Daten legst.
Ändert sich dann was an der "Struktur" musst du defines in zig Modulen 
anrühren.

Ich bleib erstmal bei diesem Konzept. Immer noch besser als per Hand 
irgendwo Adressen zu hinterlegen...

von Tom M. (tomm) Benutzerseite


Lesenswert?

key/value Paare sind eine elegante Möglichkeit, fressen aber natürlich 
mehr Speicher im eeprom als structs, und natürlich braucht's auch etwas 
Code, um diese zu parsen bzw. zu erzeugen.

Vielleicht gefällt dir ein Ansatz wie von universal binary json.

von Le X. (lex_91)


Lesenswert?

Jetzt hätt ich doch fast deine eigentliche Frage außen vor gelassen.

Solange nur ein Modul einen veränderlichen Speicherbereich braucht ist 
dein Ansatz ganz gut.

Wollen mehrere Module "dynamsich allokieren" müsstest du vorher evtl. 
abschätzen, wieviel Speicher jedes Modul maximal braucht.
Wenn du zB denkst der Datensatz wird nie größer als 100 Byte dann packst 
du eben ein 100-Byte Array mit in deine Struktur.

Ob es da elegantere Lösungen gibt, kA, mir fällt nichts ein.

von Stefan E. (sternst)


Lesenswert?

Thomas M. schrieb:
> Damit die dynamische Datenstruktur nichts
> überschreibt, darf sie natürlich erst hinter dem reservierten Bereich
> abgelegt werden.
> Ich finde jedoch keine Möglichkeit das Ende des reservierten Bereichs
> (EEMEM) zu ermitteln.

1
extern uint8_t __eeprom_end;
2
3
uint8_t *MyOwnDynamicEEdata = &__eeprom_end;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Ich finde jedoch keine Möglichkeit das Ende des reservierten Bereichs
> (EEMEM) zu ermitteln.

Der Linker legt (über den Linkerscript) ein entsprechendes Symbol
an (__eeprom_end).  Damit du das in C benutzen kannst, musst du
es aber deklarieren.
1
extern void * __eeprom_end;
2
3
int eemem[] __attribute__((section(".eeprom"))) = { 42, 24 };
4
5
int
6
main(void)
7
{
8
  return (int) &__eeprom_end;
9
}

main() würde hier den Wert 4 zurückgeben.

von Stefan E. (sternst)


Lesenswert?

le x. schrieb:
> Ganz im Gegenteil, ohne diese Struktur geht dir Modularität verloren.
> Dann müsstest du doch in jedem Modul entscheiden, an welche Stelle des
> EEPROM du nichtflüchtige Daten legst.
> Ändert sich dann was an der "Struktur" musst du defines in zig Modulen
> anrühren.

Nein, er kann auch problemlos in mehreren Modulen EEMEM Variablen 
definieren. Der Compiler (genauer Linker) kümmert sich dann um die 
Adressvergabe. Nachteil ist dann nur, dass sich diese Adressen ändern 
können. Die EEPROM-Daten als "Block" (z.B. Inhalt einer 
EEPROM-Hex-Datei) sind dann also nicht zwischen verschiedenen 
Software-Versionen austauschbar.

von Thomas M. (langhaarrocker)


Lesenswert?

Super! __eeprom_end funktioniert prima!

Ich sehe gerade dass in der *.map Datei __eeprom_end und haufenweise 
andere __* Symbole aufgeführt werden. Bestimmt kann man die bei Bedarf 
genauso für C sichtbar machen.

Problem gelöst!
Dankeschön für die Hilfe!

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.