Ich arbeite an einem Embedded-Projekt (PowerPC-Ziel, Freescale Metrowerks Codewarrior Compiler), wo die Register Memory-Mapped und in nice Bitfields definiert sind, um die einzelnen Bit-Flags einfach zu drehen.Was macht der C-Compiler mit Bitfeldern?
Im Moment verwenden wir diese Funktion, um Interrupt-Flags zu löschen und die Datenübertragung zu steuern. Obwohl ich noch keine Fehler bemerkt habe, war ich neugierig, ob das sicher ist. Gibt es eine Möglichkeit, Bitfelder sicher zu verwenden, oder muss ich jedes in DISABLE_INTERRUPTS ... ENABLE_INTERRUPTS umbrechen?
Zur Klarstellung: der Header mit dem Mikro hat Felder geliefert wie
union {
vuint16_t R;
struct {
vuint16_t MTM:1; /* message buffer transmission mode */
vuint16_t CHNLA:1; /* channel assignement */
vuint16_t CHNLB:1; /* channel assignement */
vuint16_t CCFE:1; /* cycle counter filter enable */
vuint16_t CCFMSK:6; /* cycle counter filter mask */
vuint16_t CCFVAL:6; /* cycle counter filter value */
} B;
} MBCCFR;
Ich gehe davon etwas in einem Bitfeld Einstellung nicht atomar ist. Ist das eine korrekte Annahme? Welche Art von Code erzeugt der Compiler tatsächlich für Bitfelder? Wenn ich die Maske selbst mit dem Feld R (Raw) ausführe, kann es leichter sein, sich daran zu erinnern, dass die Operation nicht atomar ist (man vergisst leicht, dass eine Zuweisung wie CAN_A.IMASK1.B.BUF00M = 1
nicht atomar ist).
Ihr Rat wird geschätzt.
Bin ich richtig in der Annahme, dass das 'v' in' vuint16_t' für "volatile" steht? – JAB
Ja, die Typen sind flüchtig, da es sich bei ihnen um Speicherkartenspeicherorte handelt. Es gibt auch Anweisungen für die Ausrichtung, die ich weggelassen habe, um die Dinge kurz zu halten. –
Vermeiden Sie Bitfelder und verwenden Sie stattdessen Maske und Verschiebung. – starblue