Forum: Mikrocontroller und Digitale Elektronik Sinnvoll EEPROM Adressen speichern?


von Ingo (Gast)


Lesenswert?

Hi,

ich speicher einige Varaiblen im EEPROM, klappt auch gut.
Jede Variable bekommt eine Adresse im EEPROM.
1
xyz = eeprom_read_word((uint16_t *)addr);

Jetzt habe ich ein Array, indem ich (noch) die Adreesen automatisch 
eintragen muss.
1
unsigned char eeprom_adresses[]={0,2,4,6,8}

wenn ich jetzt eine Variable einfüge, die sagen wir mal 32Bit, also 4 
Byte groß ist, dann muss ich das natürlich berücksichtigen bei den 
Adressen (und bei der Lesefunktion).
1
unsigned char eeprom_adresses[]={0,2,6,8,10}

So sieht das dann fertig aus.
1
xyz = eeprom_read_word((uint16_t *)eeprom_adresses["index"]);

Wie kann man jetzt, anstatt die Adressen per Hand einzutragen, dass den 
Compiler machen lassen? Mir schwebt irgendwas mit sizeof(x) vor, aber 
eine Umsetzung fehlt mir noch dazu. Jemand ne Idee?


Ingo

von Sauger (Gast)


Lesenswert?

Nabend,

falls Du mit AVRs und GCC unterwegs bist, schau dir mal EEMEM an.

könnte dann etwa so (aus dem Kopf) aussehen:

uint16_t ImEEprom EEMEM;
eeprom_read_word(&ImEEprom);

MfG

von Cyblord -. (cyblord)


Lesenswert?

Sauger schrieb:
> Nabend,
>
> falls Du mit AVRs und GCC unterwegs bist, schau dir mal EEMEM an.
>
> könnte dann etwa so (aus dem Kopf) aussehen:
>
> uint16_t ImEEprom EEMEM;
> eeprom_read_word(&ImEEprom);
>
> MfG

Jup, nimm EEMEM. Werte kannst du dann auch gleich vorbelegen. Es wird 
dann auch gleich der Platz im EEPROM angezeigt (mit avr-size) und eine 
.eep Datei mti diesen Werten erzeugt.

gruß cyblord

von Ingo (Gast)


Lesenswert?

Ja habe ich auch schon dran gedacht, aber ich möchte die Variablen nicht 
extra anlegen müssen, sondern nur kurz die Variable mit bei den Adressen 
eintragen, ein #Define für den Index machen und gut is.

Ich möchte dabei auch was lernen :)

Ingo

von spess53 (Gast)


Lesenswert?

HI

>Ich möchte dabei auch was lernen :)

Und warum dann nicht gleich das richtige lernen?

MfG Spess

von Sauger (Gast)


Lesenswert?

Nabend

> Wie kann man jetzt, anstatt die Adressen per Hand einzutragen, dass den
> Compiler machen lassen?

gegen

> Ja habe ich auch schon dran gedacht, aber ich möchte die Variablen nicht
> extra anlegen müssen, sondern nur kurz die Variable mit bei den Adressen
> eintragen, ein #Define für den Index machen und gut is.

irgendwie paradox

MfG

von Ingo (Gast)


Lesenswert?

spess53 schrieb:
> Und warum dann nicht gleich das richtige lernen?
Das da wäre?

Sauger schrieb:
> irgendwie paradox
Ja etwas, stimmt. Hast du mein Problem eigentlich begriffen?

Ich möchte statt:
1
unsigned char eeprom_adresses[]={0,2,6,8,10}
lieber
1
unsigned char eeprom_adresses[]={variable1,variable2,...}
schreiben wollen.



Ingo

von Peter D. (peda)


Lesenswert?

Warum willst Du Adressen speichern, hast Du zuviel SRAM übrig und willst 
ihn verschwenden?

C hat doch den Vorteil, daß die realen Adressen niemanden interessieren.

Wenn Du mehrere Elemente als einen Block betrachten willst, deklariere 
eine Struct. Das kostet keinen Speicher und die Elemente werden über 
ihren Zeiger referenziert.


Peter

von Ingo (Gast)


Lesenswert?

Hi Peter,
ich verstehe nicht ganz. Ich arbeite mit Variablen (Parameter) die über 
die USART Schnittstelle geändert werden. Diesel sollen natürlich 
dauerhaft erhalten bleiben, darum speichere ich sie nach jeder Änderung 
ins EEPROM. Diese Variablen sind bereits Structs. Wenn der uC startet 
lese ich einmal das EEPROM aus und weise die Werte den Parametern zu. 
Ich verwende ein Array als Adressenspeicher. Da aber auch manche 
Parameter 32 sind, nehmen die gleich 4 Byte weg bzw ich muss 4 Schritte 
im Speicher machen. Nur das möchte etwas vereinfachen. Oder gibt's ne 
bessere Lösung?

Ingo

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> Ich verwende ein Array als Adressenspeicher.

Warum?
Was willst Du mit der Adresse?


Peter

von Ingo (Gast)


Lesenswert?

Ich lege die Variable ja ins EEPROM, ich muss doch auch wissen wohin, 
oder irre ich mich?

von Sauger (Gast)


Lesenswert?

DBDBHKP :-), wie Peter schon schrieb:

Peter Dannegger schrieb:
> Wenn Du mehrere Elemente als einen Block betrachten willst, deklariere
> eine Struct. Das kostet keinen Speicher und die Elemente werden über
> ihren Zeiger referenziert.

EEMEM heist das Zauberwort. Die Adresse legt der Compiler fest. Das 
"wohin ist sie gelandet" erledigt der "&" Operator.

MfG

von Ingo (Gast)


Lesenswert?

Okay, EEMEM, ich habe eine Structure mit etwa 10 Mitgliedern. Diese 
Stuct wird etwas 15 mal gabaut. Macht etwa 150 Byte, wenn man nur von 
Chars ausgeht. Von diesen 150 will ich aber nur einen Teil wegspeichern. 
Wie kriege ich jetzt EEMEM da eingebaut? Die zu speichernde Variable 
soll aber trotzdem im SRAM bleiben.

Evtl. Packe ich sie später, wenn ganz genau klar ist, wieviele Parameter 
nicht flüchtig sein sollen gleich ins EEPROM.

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:
> Okay, EEMEM, ich habe eine Structure mit etwa 10 Mitgliedern. Diese
> Stuct wird etwas 15 mal gabaut. Macht etwa 150 Byte, wenn man nur von
> Chars ausgeht. Von diesen 150 will ich aber nur einen Teil wegspeichern.
> Wie kriege ich jetzt EEMEM da eingebaut? Die zu speichernde Variable
> soll aber trotzdem im SRAM bleiben.

Indem du dir eine Struktur baust, so WIE SIE IM EEPROM AUSSEHEN SOLL.

Von dieser Strukturdefinition erzeugst du dir ein Array mit 15 
Elementen. Das Array versiehst du mit einer EEMEM Attributierung. Und 
dann kümmert sich der Compiler darum, dass das alles im EEPROM Speicher 
angelegt wird.

Du selbst brauchst dich nicht um die Adressvergabe kümmern. Sei doch 
froh, wenn dir der Compiler diese Arbeit komplett abnimmt. Ist das 
wirklich so schwer zu verstehen?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM

von Ingo L. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ist das wirklich so schwer zu verstehen?
Ja, kannst du mir ein Beispiel geben, ich verstehe das mit der Struct 
nicht so recht.

> Von dieser Strukturdefinition erzeugst du dir ein Array mit 15
> Elementen.
DAS verstehe ich nicht.


Ingo

von Karl H. (kbuchegg)


Lesenswert?

1
#define NR_DEVICES  15
2
3
// das will ich bei einem 'Geraet' im EEPROM abspeichern
4
struct storageDaten
5
{
6
  uint8_t Bias;
7
  uint8_t Gain;
8
  uint8_t Name[15];
9
};
10
11
// dafür brauch ich Speicher, der im EEPROM residiert
12
struct storageDaten storage[NR_DEVICES] EEMEM;
13
14
// und so will ich das im SRAM Speicher haben um damit zu arbeiten
15
struct device
16
{
17
  struct storageDaten core;    // da ist zunächst mal der 'fixe' Teil
18
  uint8_t currentValue;        // und das was noch im laufenden Betrieb
19
                               // dazukommt.
20
};
21
22
// fuer die Geraet entsprechenden Speicher bereitstellen
23
struct device Devices[NR_DEVICES];
24
25
void coreToSRAM( void )
26
{
27
  for( uint8_t i = 0; i < NR_DEVICES; i++ )
28
    eeprom_read_block( &(Devices[i].core), &storage[i], sizeof(*storage) );
29
}
30
31
int main()
32
{
33
  ...
34
35
  coreToSRAM();    // Die fixen Gerätewerte aus dem EEPROM wieder herstellen
36
37
  ...
38
}


Kein Mensch muss irgendwelche EEPROM Adressen wissen.
Stell dir die EEMEM Sachen wie 'Pseudovariablen' vor. Der Compiler 
behandelt sie wie normale Variablen, verteilt sie im Speicher, es werden 
ihnen Adresse zugewiesen. Nur gibt es die Variablen so nicht. Wenn du 
ihre Werte haben willst oder verwenden willst, musst du die eeprom 
Funktion benutzen. Denen du natürlich eine Adresse übergeben musst, um 
die sich allerdings Compiler/Linker gekümmert haben. Der numerische Wert 
der Adresse ist dir wurscht - wenn du eine Variable hast (und sei es nur 
eine derartige Pseudovariable), dann kriegst du mit & ihre Adresse. 
Punkt. Alles andere ab da funktioniert genau gleich, wie mit allen 
anderen Dingen auch. Du kannst Strukturen bauen, du kannst Arrays daraus 
machen, du kannst .... In dem Moment, in dem du etwas EEMEM markierst, 
wird das Zeug in einen anderen Speicherbereich 'transferiert' und du 
kannst nur noch mit den eeprom Funktionen darauf zugreifen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Kein Mensch muss irgendwelche EEPROM Adressen wissen.
Wie war das nochmal mit der Adresse 0 bei den alten Classic-AVRs?  ;-)

EDIT:
@ Karl Heinz
> eeprom_readblock --> eeprom_read_block
Hast du ein Glück, dass du Moderator bist... ;-)

von Ingo (Gast)


Lesenswert?

@Karl-Heinz
danke für die ausführliche Erklärung. Aber um das jetzt anzuwenden ist 
meine derzeitige Datenstruktur zu weit fortgeschritten als das ich noch 
große Änderungen machen möchte. Der Ansatz ist super, werd ich beim 
nächsten Projekt berücksichtigen.


Ingo

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ingo schrieb:
> Aber um das jetzt anzuwenden ist meine derzeitige Datenstruktur zu weit
> fortgeschritten als das ich noch große Änderungen machen möchte.
Druck dir diesen Satz bitte aus, und häng ihn über deinen Schreibtisch. 
Du wirst lange deine Freude dran haben...  ;-)

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:

> große Änderungen machen möchte. Der Ansatz ist super,

Oooch.
Dann modifizier ihn halt.
1
// und so will ich das im SRAM Speicher haben um damit zu arbeiten
2
struct device
3
{
4
  struct storageDaten core;    // da ist zunächst mal der 'fixe' Teil
5
  uint8_t currentValue;        // und das was noch im laufenden Betrieb
6
                               // dazukommt.
7
};

kein Mensch sagt, dass du hier ein struct storageDaten als Member haben 
musst. Du darfst du ruhig auch einzelne Member haben, von denen einige 
aus dem EEPROM befüllt werden sollen :-)
Du musst halt nur dann deine Kopierfunktion entsprechend anpassen, die 
den EEPROM Inhalt ins SRAM holt. Das ist doch keine Raketentechnik.

> werd ich beim nächsten Projekt berücksichtigen.

:-)
Ja, ja. Das berühmte nächste Projekt. Anstatt das jetzt in 1 oder 2 
Stunden ordentlich zu machen, ärgert man sich lieber Tage mit einem Murx 
rum, nur um dann in 3 Wochen einzusehen, dass man eine Menge Zeit auf 
etwas vertrödelt hat, was vor 3 Wochen (also heute) in 1 oder 2 Stunden 
erledigt gewesen wäre.

von Ingo (Gast)


Lesenswert?

Es sind derzeit nur 11 Parameter, durchaus überschaubar die Adressen per 
Hand einzutragen.

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.