www.mikrocontroller.net

Forum: Compiler & IDEs eeprom_write_block überschreibt andere Daten


Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void SaveEEPROMParameters();
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:
uint16_t ee_foo_word      EEMEM = 300;
uint8_t  ee_foo_array[16] EEMEM = { /*16 Zahlen*/ }; 
uint16_t c_foo_word;
uint8_t  c_foo_array[16];

void SaveEEPROMParameters()
{
   printf("%u,%u",ee_foo_array,ee_foo_word);
   // führt zur Ausgabe: 200,8274
   cli();
   eeprom_write_block(&ee_foo_array,c_foo_array,sizeof(c_foo_array);
   sei();
}
void LoadEEPROMParameters()
{
   cli();
   c_foo_word = eeprom_read_word(&ee_foo_word);
   sei();
}
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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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-Tu...
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);

Autor: Tobi (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.