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
unsignedchareeprom_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).
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
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
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
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
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
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:
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
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
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
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.
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
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
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.
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... ;-)
@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
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... ;-)
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
structdevice
3
{
4
structstorageDatencore;// da ist zunächst mal der 'fixe' Teil
5
uint8_tcurrentValue;// 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.