EEPROM beim ersten Start initialiseren

Gast #2702865
Lesenswert?

Hallo Forum,

normalerweise erzeugt man im Programm EEPROM Variablen mit dem EEPROM 
Attribut.
Der gcc erzeugt dann daraus dann eine <name>.hex und <name>.eep Datei.
Beide werden mit der Programmer Software ins AVR geschrieben. So ist der 
(normale) Weg.

Aber..
- ich möchte nicht 2 Dateien haben sondern nur die HEX Datei, das EEPROM 
soll bei dem ersten Start automatisch initialisiert werden.

Meine Idee:
man lässt sich die eep Datei als binary (statt des ihex Formats) 
schreiben, das geht einfach mit "avr-objcopy -O binary".
Dann macht man daraus ein C-include (Byte Array) und kompilliert den 
Kram erneut (diesmal mit dem hinzulinken der C-include mit dem 
eeprom-Array).
Das setzt natürlich voraus, daß mein Programm beim Starten prüft, ob das 
EEPROM leer ist, wenn ja, dann das Array initial ins EEPROM schreiben. 
Wäre soweit nicht das Problem.

Mein Problem ist: wie gesagt, ich müsste 2 mal kompillieren, das 
erscheint mir irgendwie ziemlich doof und umständlich:
1. das erste mal nur um mir die .eeprom Sektion ins ELF File zu 
kompillieren und sie mit objcopy rauszuziehen
2. das zweite mal nur um das rausgezogene EEPROM File in Form von Byte 
Array wieder ins Flash zu bekommen

Gibt es eine elegante Methode?

Es soll sowas wie:
uint8_t EEPROM myByte;
weiterhin auf Adressen im EEPROM referenzieren (dh. die erste fängt bei 
0 an), damit "eeprom_write_byte()" funktioniert
und:
die .eeprom-Sektion soll irgendwo im Flash unter einem bestimmten Label 
ansprechbar sein, damit man das als Byte Array ansprechen kann um es 
initial beim ersten Start in EEPROM zu schreiben.

Habt Ihr eine Idee?

Gruß
Peter
Gast #2702886
Lesenswert?

>Gibt es eine elegante Methode?
a) 2 Dateien Flashen
b) Die Daten in eine Flash Array (Progmem) ablegen.
   Nach dem Booten ins Ram kopieren, dann prüfen ob eeprom
   OK ist (crc). Wenn ja Daten aus eeprom laden, wenn nicht
   zurückschreiben.
   Parameter werden nur im RAM geändert und bei gefallen abgespeichert.
   Damit hast du dann auch jederzeit ladbare "werkseinstellungen".
   Und falls es dein EPROM zerschießt (Brownout Detektor eingeschaltet?)
   kommt das Ding von selbst auf die Füsse.

Aber warum willst du derartige Klimmzüge machen?
2 -U beim avrdude und gut is.
#2702890
Lesenswert?

Hallo Peter,

mach dir doch ein eigenes MACRO
1
#define EEMEM_PROGMEM(var, value) ..

dass Du vor dem Includen der Steuer-Datei einfügst.
1
#define EEMEM_PROGMEM_(var_, value_) var_ PROGMEM = value_
2
#define EEMEM_PROGMEM(var_, value_) EEMEM_PROGMEM_(PRGM_##var_, value_)
3

4
#include "eemem_progmem.inc"

Als EEprom Definition könnte das so aussehen:
1
#define EEMEM_PROGMEM_(var_, value_) var_ EEMEM = value_
2
#define EEMEM_PROGMEM(var_, value_) EEMEM_PROGMEM_(EEMEM_##var_, value_)
3

4
#include "eemem_progmem.inc"

Die Steuer-Datei |eemem_progmem.inc| könnte so aussehen:
1
#ifndef _INCL_EEMEM_PROGMEM_INC
2
#define _INCL_EEMEM_PROGMEM_INC
3

4
// Definitionen
5
uint8_t EEMEM_PROGMEM(myByte0,0);
6
uint8_t EEMEM_PROGMEM(myByte1,1);
7

8
#endif
Gast #2703188
Lesenswert?

Hallo Leute, vielen Dank für die Antworten,

aber, irgendwie habt Ihr nur das wiederholt was ich geschrieben habe:
- 2 Dateien flashen (gerade das will ich nicht)
- Init Routine schreiben (das ist auch nicht die Frage, die habe ich 
auch)

noch mal:

ich möchte nicht extra ein Array selbst schreiben, sondern Gcc das 
machen lassen. Das tut er ja auch prinzipiell, in Form einer .eeprom 
Sektion im ELF.

Das mit dem Array selber schreiben hab ich bereits. Das Problem: bei 
einem größerem Projekt wird man wannsinnig bei der Pflege der Adressen 
(Offsets).
Gerade wenn es um unterschiedlich große Elemente (8, 16 und 32 bit) und 
Änderungen in der Belegung geht.

Das Schöne wäre doch sich gar nicht drum kümmern zu müssen, so wie es 
ursprünglich durch gcc vorgesehen war, nur mit dem Nachteil eine 2te 
Datei brennen zu müssen und genau diesen Nachteil mächte ich umgehen.

Den Vorschlag von Uwe S. muss ich aber erst in Ruhe nachvollziehen.

Gruß
Peter
#2703343
Lesenswert?

Leg Dir eine Struct mit allen EEPROM-Daten im Flash ab.
Nach dem Reset mache eine CRC über den EEPROM. Und wenn diese nicht 
stimmt, kopiere die struct vom Flash ins EEPROM.

Bzw. ich benutze den EEPROM nie direkt, sondern kopiere ihn in den SRAM 
bzw. beim Abspeichern zurück. Man hat dann beim Ändern nicht unnötig 
viele Zugriffe.
Dann wird die Struct im SRAM ganz normal vorbelegt, wie eine Variable.
Und nach dem Reset wird der EEPROM nur in den SRAM gelesen, wenn die CRC 
stimmt.


Peter

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