Speicherort Variabeln

OP #4008413
Lesenswert?
• ▲
▼
Hallo Gemeinde,

ich initialisiere meine Variabeln wie folgt:
1
unsigned char    EE_actualSpeed          = 0;
2
unsigned short    EE_Test              = 0;
3
unsigned char    EE_minPWM            = 10;

Nun müsste man doch meinen, dass wenn ich mit einem Zeiger
1
&EE_actualSpeed
 die Adresse 9299 auslese. Die folgende Variabel
1
 &EE_Test
 an der Adresse 9300 befinden müsste.

Dies ist leider nicht so. Kann ich da meinem xMega irgendwie unter die 
Arme greiffen um dem Compiler zu sagen, dass die Adressen hier 
eingehalten werden müssen.

Besten Dank im Voraus
#4008426
Lesenswert?
• ▲
▼
@ Pascal E. (nimmzwei)

>ich initialisiere meine Variabeln wie folgt:

>unsigned char    EE_actualSpeed          = 0;
>unsigned short    EE_Test              = 0;
>unsigned char    EE_minPWM            = 10;

Wo stehen die? In einer Funktion oder global?

>&EE_actualSpeed

> die Adresse 9299 auslese. Die folgende Variabel

> &EE_Test

> an der Adresse 9300 befinden müsste.

Nein. Die Reihenfolge und Lage von einzelnen Variablen ist NICHT 
garantiert. Das ist C, nicht ASM.

>Dies ist leider nicht so. Kann ich da meinem xMega irgendwie unter die
>Arme greiffen um dem Compiler zu sagen, dass die Adressen hier
>eingehalten werden müssen.

Ja, indem du diese Variablen in einem struc zusammenfasst. Dort MUSS der 
Compiler die Lage einhalten.
OP #4008447
Lesenswert?
• ▲
▼
Danke für die rege Beteiligung

Um Missverständnisse zu beseitigen:

Ich brauche keine Fixe Adresse, wo das Zeug steht ist im Prinzip egal. 
Wichtig ist, dass die Reihenfolge innerhalb dieses Blocks "richtig" ist.

Geht darum einen Offsett für die Ablage ins EEprom zu berechnen und so 
automatisiert die Variabeln zu übertragen.

Interessant ist für mich nur, ob mein Wunsch vom Compiler erfüllt werden 
kann.
Gast #4008461
Lesenswert?
• ▲
▼
Pascal E. schrieb:
> Bin mir nicht sicher, ob ich das soll.

warum nicht, welche bedenken gibt es?

> Habe die Lösung auf einem anderen Controller bereits lauffähig gesehen.
> Leider habe ich nicht ansatzweise eine Idee wie ich dem AVR-GCC meinen
> Wunsch aufdrücken kann.
weil C außer mit einer struct (packed!) dafür keine Möglichkeiten 
bieten.
Gast #4008462
Lesenswert?
• ▲
▼
Pascal E. schrieb:
> Nun müsste man doch meinen, dass wenn ich mit einem Zeiger
> Die folgende Variabel an der Adresse 9300 befinden müsste.

Nein.
Manche Compiler ordnen den Platz erst zu, wenn die Variabke benutzt 
wurde, und verwenden geeinsame Plätze für Variabken, die nicht gemeinsam 
verwendet werden können.
1
 void func(int i)
2
{
3
    int n=5*i;
4
    if(n>10)
5
    {
6
        int a=i-n;
7
        printf("a=\n",a);
8
    }
9
    else
10
    {
11
        int b=n-i;
12
        printf("b=\n",b);
13
    }
14
}
Da kann sich der Compiler entscheiden, n gar nicht zu speichern und a 
und b auf denselben Speicherort zu lege.

> Kann ich da meinem xMega irgendwie unter die
> Arme greiffen um dem Compiler zu sagen, dass die Adressen hier
> eingehalten werden müssen.
1
struct
2
{
3
    unsigned char    EE_actualSpeed;
4
    unsigned short    EE_Test;
5
    unsigned char    EE_minPWM;
6
}
7
EE_struct={0,0,10};
Achtung, Alignment wird gegebenenfalls EE_test nicht auf 
EE_actualSpeed+1 legen, aber eventuell EE_minPW in den Platz zwischen 
EE_actusalSpeed und EE_Test schieben, also achte auf das eingestellte 
Alignment;
#4008470
Lesenswert?
• ▲
▼
@Pascal E. (nimmzwei)

>Wichtig ist, dass die Reihenfolge innerhalb dieses Blocks "richtig" ist.

>Geht darum einen Offsett für die Ablage ins EEprom zu berechnen und so
>automatisiert die Variabeln zu übertragen.

Auch dafür braucht man keine feste Reihenfolge, denn auch EEPROM 
Variablen werden über den NAMEN angesprochen, nicht die reale Adresse. 
Um die realen
1
uint16_t varRAM;
2
uint16_t varEE EEPROM;
3

4
eeprom_write_word(&varEE, varRAM);
5
varRAM = eeprom_read_word(&varEE);

>Habe die Lösung auf einem anderen Controller bereits lauffähig gesehen.

Na dann zeig sie doch mal hier.

>Leider habe ich nicht ansatzweise eine Idee wie ich dem AVR-GCC meinen
>Wunsch aufdrücken kann.

Lese- und Schreibzugriffe laufen beim avr gcc über Funktionen. Siehe 
Doku der libc.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM
Gast #4008498
Lesenswert?
• ▲
▼
Hallo Pascal,

eigentlich gibt es nur drei Möglichkeiten, die sinnvoll sind:

a) Du vertraust dem C-Compiler (und glaub mir, der weiß was er tut!) und 
nutzt normale C-Syntax um auf Variablen zuzugreifen (Pointer, sowie 
Pointer-Arithmetik),

b) Du nutzt eine Struktur, am besten gepackt, und kannst mit 
einigermaßen Gewissheit sagen wie der Compiler diese Sturktur füllt und 
könntest nun von einer vorherigen Variable in der Struktur die Adresse 
der nächsten Ableiten - macht aber ja nicht so richtig Sinn weil du 
gleich den Variablennamen der Variable in der Struktur nehmen kannst,

c) Du weißt es besser als der C-Compiler und programmierst entweder die 
Funktion, oder gleich das komplette Programm selber in Assembler.

Sinnvollerweise wirds also wohl a) oder c) sein.

Thomas
#4008678
Lesenswert?
• ▲
▼
Thomas schrieb:
> eigentlich gibt es nur drei Möglichkeiten, die sinnvoll sind:

Es gibt mindestens noch eine 4. Möglichkeit:

d) du definierst eine eigene Sektion im EEPROM der du dann im Linker- 
skript einen Adreßbereich zuweisen kannst und weist den Compiler an, 
deine Variablen (oder die struct) in diese Sektion zu legen.

Im Prinzip macht die EEMEM Deklaration nichts anderes, nur daß die halt 
den gesamten EEPROM als eine Sektion behandelt.
#4008692
Lesenswert?
• ▲
▼
Thomas schrieb:

> b) Du nutzt eine Struktur, am besten gepackt, und kannst mit
> einigermaßen Gewissheit sagen wie der Compiler diese Sturktur füllt und
> könntest nun von einer vorherigen Variable in der Struktur die Adresse
> der nächsten Ableiten - macht aber ja nicht so richtig Sinn weil du
> gleich den Variablennamen der Variable in der Struktur nehmen kannst,

Oder aber. Man kopiert ganz einfach das komplette Strukturobjekt so wie 
es ist, ohne sich weiter um seine inneren Aufbau kümmern zu müssen.
Das macht dann am allermeisten Sinn, weil man ein Ding weniger hat, um 
das man sich kümmern muss.
1
struct MotorData
2
{
3
  unsigned char   actualSpeed;
4
  unsigned short  Test;
5
  unsigned char   minPWM;
6
};
7

8
struct MotorData Motor1 = { 0, 0, 10 };   // Das Objekt im Speicher
9

10
struct MotorData EE_Motor EEMEM;          // Die Variante davon im EEPROM
11

12
.....
13
   // Vom EEProm in den Speicher
14
   eeprom_read_block( &Motor1, &EE_Motor, sizeof( Motor1 ) );
15
...
16
  // Vom Speicher ins EEPROM
17
   eeprom_write_block( &Motor1, &EE_Motor, sizeof( Motor1 ) );


Pascal schrieb
> Bin mir nicht sicher, ob ich das soll.

Doch. Genau das sollst du. Und wenn du schon dabei bist, sollst du auch 
noch ein C-Buch kaufen und durcharbeiten.

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