Forum: Compiler & IDEs EEMEM: Initialisierung von Strukturen


von Sören (Gast)


Lesenswert?

Hallo zusammen,

in einem Projekt soll das EEPROM vorbelegt werden. Dazu wird
EEMEM eingesetzt, was auch ganz gut funktioniert.
Probleme gibt es, wenn eine Struktur initialisiert werden soll.
Dieser Beitrag Beitrag "EEMEM und Strukturen" hilft
leider nicht weiter, da hier zur Initialisierung nicht auf die
Elemente der Struktur zugegriffen wird.


>> myInclude.h
1
typedef struct  
2
{
3
  uint8_t a;
4
  uint8_t b;
5
} sMyStruct;
6
7
extern uint8_t  fred;
8
extern sNode  myList[5];

>> myMain.c
1
#include <avr/eeprom.h>
2
#include "myInclude.h"
3
4
uint8_t EEMEM  fred    = 0xFF;
5
sMyStruct EEMEM  myList[5];
Das compiliert ohne Probleme.
Wenn dann aber eine Initialisierung eingefügt wird
1
sMyStruct EEMEM  myList[5];
2
                 myList[0].a  = 0xAA;
gibt der Compiler diesen Fehler aus:
1
Error  1  expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
Wenn das dann in eine Funktion gepackt wird, verschwindet der Fehler
natürlich:
1
sMyStruct EEMEM myList[5];
2
void myFunc (void) {
3
     myList[0].a    = 0xAA;
4
}
Damit wird die gewünschte EEPROM-Initilisierung zur Compile-Zeit aber
leider nicht erreicht.

Ich würde mich freuen, wenn jemand eine Idee hat. Vielen Dank!

Schöne Grüße
Sören

: Bearbeitet durch User
von Klaus F. (kfalser)


Lesenswert?

Sören schrieb:
> sMyStruct EEMEM  myList[5];
>                  myList[0].a  = 0xAA;

Das ist ja auch keine Initialisierung (C Buch gelesen ?)!
1
 
2
sMyStruct EEMEM  myList[5] = {{ 0xAA, 0xBB},
3
                              { 0xAA, 0xBB}, 
4
                              { 0xAA, 0xBB}, 
5
                              { 0xAA, 0xBB}, 
6
                              { 0xAA, 0xBB}};
funktioniert vielleicht eher.

von Sören (Gast)


Lesenswert?

Danke schon mal für die schnelle Rückmeldung.
Der Vorschlag funktioniert und wurde auch so im zitierten Foren-Beitrag 
erfolgreich umgesetzt.

Das Projekt ist allerdings etwas komplexer als das beschriebene Beispiel 
zeigt. Deshalb würde ich gern die Komponenten der Struktur einzeln 
initialisieren, um das ganze übersichtlicher zu haben. Im Web gibt es 
dazu auch diverse Beispiele, z.B. 
http://www.c-howto.de/tutorial-strukturierte-datentypen-strukturen-struct-felder-zeiger.html, 
was hier aber dieser Fehlermeldung führt.

von Peter II (Gast)


Lesenswert?

Sören schrieb:
> Deshalb würde ich gern die Komponenten der Struktur einzeln
> initialisieren, um das ganze übersichtlicher zu haben.

das geht nicht. Dann ist es nur eine Zuweisung keine Initialisierung.

von Sören (Gast)


Lesenswert?

uint8_t EEMEM  fred    = 0xFF;

Ist dann Zuweisung oder Initialisierung? Jedenfalls steht das dann 
tatsächlich im EEPROM.

von Peter II (Gast)


Lesenswert?

Sören schrieb:
> uint8_t EEMEM  fred    = 0xFF;
>
> Ist dann Zuweisung oder Initialisierung? Jedenfalls steht das dann
> tatsächlich im EEPROM.

Initialisierung

von holger (Gast)


Lesenswert?

>Deshalb würde ich gern die Komponenten der Struktur einzeln
>initialisieren, um das ganze übersichtlicher zu haben.

Du scheinst noch nicht begriffen zu haben das es keine
Variablen im EEPROM gibt. Zum lesen und schreiben des
EEPROMs gibt es spezielle Funktionen. Die fangen an mit

eeprom_read
eeprom_write

von Sören (Gast)


Lesenswert?

holger schrieb:
>>Deshalb würde ich gern die Komponenten der Struktur einzeln
>>initialisieren, um das ganze übersichtlicher zu haben.
>
> Du scheinst noch nicht begriffen zu haben das es keine
> Variablen im EEPROM gibt. Zum lesen und schreiben des
> EEPROMs gibt es spezielle Funktionen. Die fangen an mit
>
> eeprom_read
> eeprom_write

Die Ablage einzelner Bytes im EEPROM ist mir geläufig, auch deren 
Initialisierung mit EEMEM.

Meine Frage bezog sich darauf, wie Strukturen im EEPROM auf die gleiche 
Art initialisiert werden können. Der Übersichtlichkeit wegen sollte das 
aber nicht durch geschweifte Klammern und eine Liste der Werte sondern 
durch Zugriff auf die einzelnen Komponenten der Struktur geschehen.
Das Auslesen oder Ändern dieser Werte geschieht dann natürlich mit den 
genannten Funktionen aus eeprom.h.

von Peter D. (peda)


Lesenswert?

Initialisierungen müssen in {} stehen.
z.B.:
1
typedef union {
2
  struct{
3
    uint16_t flow_min;
4
    uint16_t temp_min;
5
    uint16_t temp_max;
6
    uint16_t press_max;
7
    uint16_t mode;
8
  }p;
9
  uint16_t v[5];
10
}ccx_wr;
11
12
ccx_wr ccx_wr_data = {
13
                        .p.flow_min  = 3000,
14
                        .p.temp_min  = 20000,
15
                        .p.press_max = 8000,
16
                        .p.temp_max  = 35000,
17
                        .p.mode = 1,
18
                     };

von Klaus F. (kfalser)


Lesenswert?

Sören schrieb:
> Meine Frage bezog sich darauf, wie Strukturen im EEPROM auf die gleiche
> Art initialisiert werden können.
Das geht nicht, das wäre dann nicht mehr C.

> Der Übersichtlichkeit wegen sollte das
> aber nicht durch geschweifte Klammern und eine Liste der Werte sondern
> durch Zugriff auf die einzelnen Komponenten der Struktur geschehen.
Siehe oben. In C muss man halt die Initialisierung so machen, auch Du 
das nicht übersichtlich findest.
Neuere Versionen von C bieten jedoch die Methode mit den Element-Namen, 
so wie sie Peter aufgezeigt. In diesem Fall braucht auch die Reihenfolge 
der Elemente nicht zu stimmen, bzw. man kann auch welche weglassen.

von Ralf G. (ralg)


Lesenswert?

Sören schrieb:
> Der Übersichtlichkeit wegen sollte das
> aber nicht durch geschweifte Klammern und eine Liste der Werte sondern
> durch Zugriff auf die einzelnen Komponenten der Struktur geschehen.

Nur das ist eine Initialisierung:
Typ Variable = Irgendwas;
Wenn du der Variablen später einen Wert gibst, dann ist das eine 
Zuweisung, die während des Programmlaufes erledigt wird.

Um die Variablen, die im RAM landen, kümmert sich ausnahmsweise 
(Flash->RAM) das Programm ganz am Anfang.

Alle Initialisierungen, die im EPROM landen sollen, musst du selbst dort 
hinschreiben. Da bekommst du nach der Übersetzung nur eine 'Datei zum 
brennen' geliefert.

von Sören (Gast)


Lesenswert?

Das waren sehr hilfreiche Antworten. Danke euch allen.

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.