Wie man laut Bild oben sieht, hat dieses Register (32 Bit, okay das kann
man im Bild jetzt nicht erkennen, egal) [0..3] 4 Bit´s.
Dies wollte Ich nun mit "enum" niederschreiben.(die anderen Bits sollen
folgen..)
Ist das so optimal wie Ich das vor habe?
Im Prinzip kann man das so machen. enums oder defines sind typisch zum
Definieren von Konstanten.
Aber, DSP_CR1_CLRSS_TO1 in deinem Beispiel ist wahrscheinlich falsch.
Das umfast 4 Bits und vermutlich macht eine Definition als Bit-Maske
oder mehrere individuelle Werte (maximal 8) mehr Sinn.
Mark schrieb:> Im Prinzip kann man das so machen. enums oder defines sind typisch> zum> Definieren von Konstanten.>> Aber, DSP_CR1_CLRSS_TO1 in deinem Beispiel ist wahrscheinlich falsch.> Das umfast 4 Bits und vermutlich macht eine Definition als Bit-Maske> oder mehrere individuelle Werte (maximal 8) mehr Sinn.
Wie würdest du das machen?
Achim S. schrieb:> ...> /* Mapping einer Variable auf das HW-Register, */> volatile struct sConfigReg ConfigReg @ 0x800200;> /* keine Ahnung, wie es bei Dir geht */> [/c]
Was genau soll das bezwecken? Was macht '@'?
Jan H. schrieb:> Kann man die Bitfelder auch auf Array´s anwenden?
Ja.
1
structsConfigRegConfigReg[12];
ist problemlos möglich.
Jan H. schrieb:>> volatile struct sConfigReg ConfigReg @ 0x800200;> Was genau soll das bezwecken? Was macht '@'?
naja, irgendwie muss der Compiler wissen, dass dieses Register an einer
konkreten Stelle im Speicher steht. Dafür hat jeder Compiler seine
eigene Notation.
Jan H. schrieb:> struct> {> enum dfeCR1Bits bitsReg1;> enum dfeCR2Bits bitsReg2;> uint32_t reg[2];> }dfeControl
Bist Du sicher, dass Du in Deinem Code struct, Union und Bitfelder
auseinander hälst? Ich fürchte, Du möchtest Das Array jeweils alternativ
zu den enums, oder?
Achim S. schrieb:> Jan H. schrieb:>>> volatile struct sConfigReg ConfigReg @ 0x800200;>> Was genau soll das bezwecken? Was macht '@'?> naja, irgendwie muss der Compiler wissen, dass dieses Register an einer> konkreten Stelle im Speicher steht. Dafür hat jeder Compiler seine> eigene Notation.
Ich programmiere mit Atmel Studio 7, wie mache Ich das dort?
Achim S. schrieb:> Jan H. schrieb:>> struct>> {>> enum dfeCR1Bits bitsReg1;>> enum dfeCR2Bits bitsReg2;>> uint32_t reg[2];>> }dfeControl>> Bist Du sicher, dass Du in Deinem Code struct, Union und Bitfelder> auseinander hälst? Ich fürchte, Du möchtest Das Array jeweils alternativ> zu den enums, oder?
Ich möchte zu dem jeweiligen Register vom Chip die Bits haben. Daher
habe Ich in jedem struct das dafür geschriebene "enum" mit in die
jeweilige struct mit eingeführt.
Achim S. schrieb:> Jan H. schrieb:>> Kann man die Bitfelder auch auf Array´s anwenden?>> Ja.struct sConfigReg ConfigReg[12]; ist problemlos möglich.
Und wie?
Eric B. schrieb:> Achim S. schrieb:>>> struct sConfigReg>> {>> uint32 CLRSS_TO1 : 4;>> uint32 ClearSS1 : 1;>> uint32 ENVREF1 : 1;>> uint32 TC1 : 3;>> };> ...> Und dann hoffen/wissen ob der Compiler das Bitfield CLRSS_TO1 in den> höchsten oder niedrigsten vier Bits im Register legt.
Wie genau funktioniert das? Wenn ich 12 Arrayelemente habe?
Oder wird so das ganze "Array Struct" definiert? Dann hätten ja alle 12
Arraymitglieder diese Zuordnung?
Eric B. schrieb:> Und dann hoffen/wissen ob der Compiler das Bitfield CLRSS_TO1 in den> höchsten oder niedrigsten vier Bits im Register legt
Nein. Das stellt man sicher, indem man
- die Anleitung des Compilers dazu liest
- es exemplarisch ausprobiert
- es per assert überwacht
Und wer bitfelder nicht mag, weil sie nicht portabel sind, lässt es.
Wobei ich das Argument bei den Registern eines Prozessors nicht
wirklich stichhaltig finde.
Jan H. schrieb:> Ja.struct sConfigReg ConfigReg[12]; ist problemlos möglich.> Und wie?
Wenn du
1
structsConfigRegConfigReg[12];
schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche
Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).
Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.
Hast Du denn jeweils n gleiche Bitfelder?
D
Achim S. schrieb:> struct sConfigReg ConfigReg[12];> schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche> Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).>> Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.>> Hast Du denn jeweils n gleiche Bitfelder?
Das ist ja eben die Sache. Die Register haben alle andere Bits.
Dann klappt das so nicht oder?
Helmut A. schrieb:> D>> Achim S. schrieb:>> struct sConfigReg ConfigReg[12];>> schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche>> Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).>>>> Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.>>>> Hast Du denn jeweils n gleiche Bitfelder?> Das ist ja eben die Sache. Die Register haben alle andere Bits.> Dann klappt das so nicht oder?
Stehst du vor dem gleichen Problem?
Achim S. schrieb:> Wobei ich das Argument bei den Registern eines Prozessors nicht> wirklich stichhaltig finde.
Naja, so ein volatiles Bitfeld kann glaube ich ganz, ganz übel nach
hinten losgehen, was den generierten Code angeht. Wenn man einen
uint32_t in Bits zerschnitten hat, soll der Compiler dann nur ein Byte
davon updaten, wenn er kann oder immer alles auf einmal?
Heiko L. schrieb:> Achim S. schrieb:>> Wobei ich das Argument bei den Registern eines Prozessors nicht>> wirklich stichhaltig finde.>> Naja, so ein volatiles Bitfeld kann glaube ich ganz, ganz übel nach> hinten losgehen, was den generierten Code angeht. Wenn man einen> uint32_t in Bits zerschnitten hat, soll der Compiler dann nur ein Byte> davon updaten, wenn er kann oder immer alles auf einmal?
???
Wenn man es verODERt? Was geht das verloren?
Es soll nur das Bit gesetzt werden was gerade benötigt wird.
Man könnte z.B. auf die Idee kommen, einen Byte-Write daraus zu machen,
wenn nur a geschrieben wird. Im Falle von Hardware-Registern kann es
aber einen echten Unterschied machen, ob die restlichen Felder noch
einmal mitgeschrieben werden oder nicht, bzw. können solche 1/4-Writes
auf Register -Locations auch ganz verboten sein. Da muss man echt
entweder seinem Compiler echt Vertrauen bzw. ihn im Griff haben oder
Vorsichtig sein, was man mit solchen Variablen tut.
Zum Beispiel sollte
1
void f() {
2
S s = *reg;
3
s.a = 3;
4
*reg = s;
5
}
relativ sicher sein, auch wenn man bei gcc das
"-fstrict-volatile-bitfields" vergessen hat oder sich da mal wieder ein
Fehler eingeschlichen hat.