Sinnvoll EEPROM Adressen speichern?

Gast #2563481
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
#2563502
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
Gast #2563530
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
Gast #2563540
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
#2563562
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
Gast #2563581
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
Gast #2563609
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
Gast #2563630
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.
#2563977
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
#2564157
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.
Gast #2564481
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
#2564531
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren