Hallo Gemeinde,
ich initialisiere meine Variabeln wie folgt:
1
unsignedcharEE_actualSpeed=0;
2
unsignedshortEE_Test=0;
3
unsignedcharEE_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
@ 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.
@ Mark Brandis (markbrandis)
>> dass die Adressen hier eingehalten werden müssen.>Wozu?
Berechtigte Frage. Denn normaleweise hat man in C mit absoluten Adressen
nix zu tun, man greift immer über den Variablennamen auf Variablen zu.
Falk Brunner schrieb:> man greift immer über den Variablennamen auf Variablen zu.
oder Pinter, welch Adresse jetzt aber genau im Pointer steht
interessiert meistens niemanden.
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.
PittyJ schrieb:> Dann solltest du wirklich mit einem struct arbeiten, und die Variablen> darin zusammen fassen.
Bin mir nicht sicher, ob ich das soll.
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.
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.
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
voidfunc(inti)
2
{
3
intn=5*i;
4
if(n>10)
5
{
6
inta=i-n;
7
printf("a=\n",a);
8
}
9
else
10
{
11
intb=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
unsignedcharEE_actualSpeed;
4
unsignedshortEE_Test;
5
unsignedcharEE_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;
@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_tvarRAM;
2
uint16_tvarEEEEPROM;
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
Im AVR Codevision gibt es die möglichkeit über @ die Adresse
festzulegen.
also: unsigned char EE_actualSpeed@0x5000;
Ansonsten gibts evtl. sowas wie
#pragma DATA_SECTION(...);
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
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.
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
structMotorData
2
{
3
unsignedcharactualSpeed;
4
unsignedshortTest;
5
unsignedcharminPWM;
6
};
7
8
structMotorDataMotor1={0,0,10};// Das Objekt im Speicher
9
10
structMotorDataEE_MotorEEMEM;// Die Variante davon im EEPROM
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.