www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik mehrere Variablen in EEPROM speichern


Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich mehrere Zahlen-Variablen ins EEPROM speichern möchte, muß ich 
mir dafür die Funktion eeprom_write_block hernehmen oder geht das auch 
mit eeprom_write_byte.

Falls ja, ich versuche gerade 2 Variablen zu schreiben und zu lesen:
volatile uint8_t nKonfig;
volatile uint8_t light;

volatile uint8_t EEMEM eeprom_tasten = 1;
volatile uint8_t EEMEM eeprom_lcd = 2;

int main(void)
{
  init();                            // Einschaltsequenz starten
  sei();                            // Interrupts aktivieren

  lcd_update();

  nKonfig = (eeprom_read_byte(&eeprom_tasten));
  light = (eeprom_read_byte(&eeprom_lcd));
...
Der compiler kommt mir jedoch mit einer Warnung:

../main.c:351: warning: passing argument 1 of '__eerd_byte_m8' discards 
qualifiers from pointer target type

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Code widerspricht so ziemlich allem, was im AVR-GCC-Tutorial 
über EEPROM geschrieben steht.

#include <avr/io.h>
#include <avr/eeprom.h>

#define BLOCKGROESSE 42

// Daten im RAM
volatile uint8_t nKonfig;
volatile uint8_t light;
uint16_t ramblock[BLOCKGROESSE];

// Daten im EEPROM
volatile uint8_t eeprom_tasten EEMEM = 1;
volatile uint8_t eeprom_lcd EEMEM = 2;
uint16_t eepromblock[BLOCKGROESSE] EEMEM = { 13, 11, 42 };

int main(void)
{
  // Daten aus den EEPROM Variablen in die RAM Variablen schaufeln
  // Byte for Byte Qualitait
  nKonfig = eeprom_read_byte(&eeprom_tasten);
  light = eeprom_read_byte(&eeprom_lcd);

  // Blocktransfer
  eeprom_read_block(ramblock, eepromblock, sizeof(eepromblock))

  while(1);
}


Über die Dekoration volatile würde ich zumindest bei den EEPROM-Daten 
nochmal nachdenken. Die dürften seltenst sinnvoll in einer ISR geändert 
werden... Ohne volatile kommt auch die Warnung nicht.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, habe auch genau dieses Problem, dass die Warnung kommt. Aber ich 
möchte die Variable im EEPROM in einer ISR ändern, nämlich wenn über den 
RXT interrupt Parameter geändert werden, welche im EEPROM stehen. 
Wegcasten kann man diese Warnung auch nicht! Was also tun damit die 
Warnung verschwindet?

Ich Grabe die Leiche wieder aus, dann spare ich mir einen neuen Beitrag.

Ingo

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo schrieb:
> Aber ich
> möchte die Variable im EEPROM in einer ISR ändern

EEPROM schreiben kostet pro Byte 8ms. Möchtest Du wirklich, daß Dein 
Programm abschmiert, weil die CPU so elendig lange stehen bleibt?

Generell hat man für EEPROM-Daten immer eine Arbeitskopie im SRAM.
Und nur bei Bedarf wird der EEPROM damit geupdatet.
Entweder im Main, damit die Interrupts weiter laufen.
Oder ganz clever im EEPROM-Interrupt ohne jede Zeitvergeudung.


Ingo schrieb:
> Ich Grabe die Leiche wieder aus, dann spare ich mir einen neuen Beitrag.

Nicht gut, da Dein Problem ja ein völlig anderes ist.


Peter

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein ist kein Anderes, ist absolut das selbe. Du weißt weder ob sich 
mein ganzes Programm in einer ISR abspielt oder sonst was. Also nur die 
eigentliche Frage beantworten. Trotzdem danke für den Hinweis.


Ingo

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo schrieb:
> Du weißt weder ob sich
> mein ganzes Programm in einer ISR abspielt

Ich gehe eben von einem sinnvollen Programmkonzept aus.
Kann gut sein, daß ich damit manchen besser einschätze, als er ist.

Aber Du hast irgendwie doch recht, wir wissen garnichts.
Du hast nichts mitgeteilt, also können wir auch nicht helfen.
Jeder weiß eigentlich, bei Programmierfragen ist ein Quellcode als 
Anhang und die exakte Fehlermeldung mit Zeilennummer das mindeste.


Peter

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo schrieb:
> Wegcasten kann man diese Warnung auch nicht!

Klar kann man das.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Ingo schrieb:
>> Wegcasten kann man diese Warnung auch nicht!
>
> Klar kann man das.

Ja, aber wenn ich das so schreiben würde:
volatile unsigned int temp=0;
...
temp = eeprom_read_byte (&eeFooByte));
meckert der Compiler.

mache ich es so

volatile unsigned int temp=0;
...
temp =  eeprom_read_byte (&(unsigned int)eFooByte));

kommt er mir dem "&" durcheinander hält es für eine logische UND 
Verknüpfung.

Ingo

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo schrieb:

> Ja, aber wenn ich das so schreiben würde:
>
> volatile unsigned int temp=0;
> ...
> temp = eeprom_read_byte (&eeFooByte));
> 
> meckert der Compiler.

'meckert der Compiler' ist keine vernünftige Fehlermeldung.
Auch wenn es manchmal nicht so aussieht: Fehlermeldungen haben einen 
Grund und der Grund ist in der Fehlermeldung enthalten. Ich gebe zu, 
manchmal ist es schwer den Grund zu entdecken, wenn man die C-Syntax 
noch nicht so drauf hat.

> volatile unsigned int temp=0;
> ...
> temp =  eeprom_read_byte (&(unsigned int)eFooByte));
> [/c]
>
> kommt er mir dem "&" durcheinander hält es für eine logische UND
> Verknüpfung.

Nö, das tut er nicht.
Eine Und Verknüpfung hat immer eine linke Seite und eine rechte Seite

    a & b

Das ist hier nicht der Fall, also kann es auch kein Und sein. Das weiß 
auch der Compiler. Und du kannst davon ausgehen, dass der Compiler die 
C-Syntax sehr viel besser kennt als du.

Aber: Durch das Umcasten eines Bytes zu einem unsigned int, hast du eine 
temporäre Variable erzeugt (eben den unsigned int) und von dem kannst du 
nicht die Adresse nehmen. Daher kann "&(unsigned int)eFooByte" nicht 
richtig sein.

Das ist aber auch nicht das was du wolltest.
Du wolltest die Adresse von eFooByte nehmen.
Und das schreibt sich als

    &eFooByte

und dann diese Adresse als die Adresse eines unsigned int aufgefasst 
wissen:
    (unsigned int*)&eFooByte


Damit, dass du links vom = einen unsigned int hast, hat das herzlich 
wenig zu tun. Du kannst nicht dadurch, dass du der Funktion den 
Adressdatentyp eines unsigned int unterjubelst (selbst wenn du das 
richtig gemacht hättest - "(unsigned int*) &eFooByte" ) die Funktion 
dazu bringen, dass sie etwas anderes tut als ein einzelnes Byte 
auszulesen.

Also: Wie lautet die Fehlermeldung im genauen Wortlaut. Damit fängt 
jegliche Analyse an. "meckert der Compiler" ist kein genauer Wortlaut. 
Und dann sieht man sich eben alle Datentypen der beteiligten Operationen 
an und kontrolliert, wo man den Fehler gemacht hat.

Eine Warnung bezüglich Datentypen kann man IMMER wegcasten. Letzten 
Endes ist ein derartiger Cast die Anweisung an den Compiler: "Halt's 
Maul, ich weiß es besser." Nur sollte man auch sicher gehen, dass man es 
auch wirklich besser weiß.

Autor: Mw En (Firma: fritzler-avr.de) (fritzler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das heist dann ja auch so:
((unsigned int*)&eFooByte))

Natürlich gehen mehrere Variablen ins EEPROM, kannst die Adresse 
jedesmal ändern, musst nur aufpassen, dass du nix überschreibst.
writeword belegt zB 2 Adressen, steht aber alles hier auf 
Anleitungsseiten

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, danke für die Antworten. Ich habe diesen Tread wieder aufgemacht, 
weil ich die Warnung (erster Beitrag) auch bekomme, wenn ich die 
Variable volatile mache. Mein Cast ist offensichtlich falsch gewesen, so 
wie es Karl-Heinz und Martin geschrieben haben.

Ich habe nur das selbe Problem gehabt wie der TE, jedoch will ich keine 
2 Variablen oder sonst was machen, geht nur darum das volatile 
wegzucasten.

Danke

Ingo

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wobei sich allerdings die Frage erhebt, wozu man EEMEM Variablen 
überhaupt als volatile markiert.
Diese 'Variablen' sind nur ein Hilfskonstrukt, damit man eine 
Adressallokierung im EEPROM bekommt. Machen kann man mit diesen 
Variablen sowieso nichts, ausser die eeprom_xxxx Funktionen mit ihren 
Adressen aufrufen. Und die kann ein Compiler sowieso nicht 
wegoptimieren.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Somit währe volatile überflüssig, selbst wenn ich sie in einer isr 
verändere?


Ingo

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo schrieb:
> Somit währe volatile überflüssig, selbst wenn ich sie in einer isr
> verändere?

Welches volatile?
Das hier?
volatile uint8_t EEMEM eeprom_tasten = 1;

Das ist eine EEMEM Variable. Was soll das volatile denn hier bewirken?


Oder ist dir nicht klar, worum es bei volatile eigentlich geht?
http://www.mikrocontroller.net/articles/FAQ#Was_ha...

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im, meine Fragen sind beantwortet, besten Dank.


Ingo

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.