Forum: Compiler & IDEs eeprom_write_block überschreibt andere Daten


von Tobi (Gast)


Lesenswert?

Hallo,
ich kämpfe gerade mit den eeprom Routinen rum, und komme irgendwie nicht 
weiter. Für die Parameter eines Steuergerätes habe ich 2 Funktionen 
geschrieben:
1
void SaveEEPROMParameters();
2
void LoadEEPROMParameters();
Wie die Namen vermuten lasse dienen diese dazu die 
Konfigurationsparameter ins EEPROM zu sichern und zu laden. Ich hatte 
immer wieder Probleme, dass nach dem wegsichern mit 
SaveEEPROMParameters() manche Daten danach ungültig waren. Mittlerweile 
habe ich den Code dahingehend gekürzt, dass sich der Fehler noch 
reproduzieren lässt:
1
uint16_t ee_foo_word      EEMEM = 300;
2
uint8_t  ee_foo_array[16] EEMEM = { /*16 Zahlen*/ }; 
3
uint16_t c_foo_word;
4
uint8_t  c_foo_array[16];
5
6
void SaveEEPROMParameters()
7
{
8
   printf("%u,%u",ee_foo_array,ee_foo_word);
9
   // führt zur Ausgabe: 200,8274
10
   cli();
11
   eeprom_write_block(&ee_foo_array,c_foo_array,sizeof(c_foo_array);
12
   sei();
13
}
14
void LoadEEPROMParameters()
15
{
16
   cli();
17
   c_foo_word = eeprom_read_word(&ee_foo_word);
18
   sei();
19
}
Führe ich nun die Load-Funktion aus, hat c_foo_word den erwarteten Wert 
300. Rufe ich danach dann SaveEEPROMParameters  auf, und lade 
anschließend die Werte wieder, hat sich der Wert von ee_foo_word 
verändert, obwohl auf diesen nicht schreibend zugegriffen wird. Über die 
serielle Schnittstelle habe ich zuvor mal einen Ausgabe gesetzt die mir 
die Adressen der beiden Variablen im EEPROM anzeigen soll, die Ausgabe 
"200,8274" verstehe ich nicht ganz, denn demnach würde die beiden ca 8K 
voneinander entfernt liegen. Im Einsatz ist ein ATMEGA32 mit 1KB EEPROM. 
Jemand eine Idee woran es liegen könnte?

LG Tobi

System:
µC:ATMEGA32
Compiler: avr-gcc 3.4.6
OS: Mac OS 10.6

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Tobi schrieb:

> uint8_t  ee_foo_array[16] EEMEM = { /*16 Zahlen*/ };
> ...
>    eeprom_write_block(&ee_foo_array,c_foo_array,sizeof(c_foo_array);
                        ^

Kontrolliere bzw. korrigiere das &. Näheres siehe AVR-GCC-Tutorial. Die 
Zeile müsste auch im Compiler einen Syntaxfehler erzeugen, weil eine 
schliessende Klammer fehlt.

>    printf("%u,%u",ee_foo_array,ee_foo_word);

Solltest du auch noch mal checken. Werte aus dem EEPROM (und ROM) liest 
man mit bestimmten Funktionen aus. Die Kurzform ohne Funktionen beim 
EEPROM geht nur beim neusten AVR-GCC.

"%u", Arrayname gibt kein Element des Arrays aus, sondern den Wert von 
Arrayname also eine Adresse.

"%u", ee_foo_word hingegen gibt keine Adresse aus. Dazu müsstest du 
"%u", &ee_foo_word verwenden.

von Tobi (Gast)


Lesenswert?

>> uint8_t  ee_foo_array[16] EEMEM = { /*16 Zahlen*/ };
>> ...
>>    eeprom_write_block(&ee_foo_array,c_foo_array,sizeof(c_foo_array);
>                        ^
>
>Kontrolliere bzw. korrigiere das &. Näheres siehe AVR-GCC-Tutorial. Die
>Zeile müsste auch im Compiler einen Syntaxfehler erzeugen, weil eine
>schliessende Klammer fehlt.
Wieso den Adressoperator korrigieren? Auch im AVR-GCC-Tutorial auf 
dieser Seite wird es immer verwendet, was ja auch gewissermaßen logisch 
ist, da ja die Adresse intressiert, nicht der Wert. Die Klamemr 
existiert im orginalcode, ist beim editieren dieses Beitrags von mir 
wohl versehentlich gelöscht worden.

>>    printf("%u,%u",ee_foo_array,ee_foo_word);
>Solltest du auch noch mal checken. Werte aus dem EEPROM (und ROM) liest
>man mit bestimmten Funktionen aus...
Wollte an der Stelle mir die Adressen der eeprom-variablen auch ausgeben 
und nicht deren Inhalt, da genau diese Adressen ja später der 
eeprom_write_block Funktion übergeben werden. Das Auslesen aus dem 
EEPROM geschieht in der LoadEEPromParameters. Diese Codezeile habe ich 
wie gesagt nachträglich zur Überprüfung eingebaut.

von Tobi (Gast)


Lesenswert?

Korrektur:

>>    printf("%u,%u",ee_foo_array,ee_foo_word);
>Solltest du auch noch mal checken. Werte aus dem EEPROM (und ROM) liest
>man mit bestimmten Funktionen aus...
Habe da natürlich die Adressoperatoren vergessen. Habe sie nun eingefügt 
und die Ausgabe lautet nun 200,228. Das klingt für mich eher plausibel 
da es innerhalb der 1K Grenze des µC liegt. Auch überlappt sich der 
Bereich wohl nicht.

Jemand noch eine Idee, wo der Fehler liegen könnte?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Tobi schrieb:
>>> uint8_t  ee_foo_array[16] EEMEM = { /*16 Zahlen*/ };
>>> ...
>>>    eeprom_write_block(&ee_foo_array,c_foo_array,sizeof(c_foo_array);
>>                        ^
>>
>>Kontrolliere bzw. korrigiere das &. Näheres siehe AVR-GCC-Tutorial. Die
>>Zeile müsste auch im Compiler einen Syntaxfehler erzeugen, weil eine
>>schliessende Klammer fehlt.

> Wieso den Adressoperator korrigieren? Auch im AVR-GCC-Tutorial auf
> dieser Seite wird es immer verwendet, was ja auch gewissermaßen logisch
> ist, da ja die Adresse intressiert, nicht der Wert.

Wenn du meinst.

Ich sehe das im Abschnitt
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Block_lesen.2Fschreiben
anders (und dort ist es richtig entgegen dem Korrekturversuch letzte 
woche siehe Diskussion dort).

Ich schlage vor: lies ein C-Buch zum Abschnitt Arrays/Felder und lies 
die Doku der EEPROM Funktionen im Manual der avr-libc.

>>>    printf("%u,%u",ee_foo_array,ee_foo_word);

> Wollte an der Stelle mir die Adressen der eeprom-variablen auch ausgeben
> und nicht deren Inhalt, da genau diese Adressen ja später der
> eeprom_write_block Funktion übergeben werden.

Dann so:

  printf("%u,%u", ee_foo_array, &ee_foo_word);

von Tobi (Gast)


Lesenswert?

hab Fehler gefunden. Die Parameter bei eeprom_write_block haben wohl die 
Reihenfolge Ziel, Quelle, im Gegensatz zu eeprom_write_word :)

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.