2017-02-21 6 views
0

Stellen Sie sich vor! Ich erhalte 8 Bytes als uint8_t data[8] von einer IO-Schnittstelle, die einige Hausautomation verarbeitet. Diese acht Bytes werden müssen, wie Brachen interpretiert:Zugriff auf Bits im zugeordneten Speicher?

Memory interpretion

Wie greife ich auf die richtigen Bits? Ich dachte, jetzt über zwei Lösungen:

Lösung 1: eine Struktur mit einigen bitfields definieren:

struct data_s { 
    uint8_t LightSwitch0:1; 
    uint8_t LightSwitch1:1; 
    uint8_t LightSwitch2:1; 
    uint8_t LightSwitch3:1; 
    uint8_t Brightness:4; 
    uint8_t Dimmer0; 
    uint8_t Dimmer1; 
    uint8_t Dimmer2; 
    uint8_t Dimmer3; 
    uint8_t Dimmer4; 
    uint8_t DoorSwitch:1; 
    uint8_t Spare:7; 
} 

Weiter konnte ich einfach eine Besetzung haben und die structs Mitglieder in diesem Beispiel nach Zugang:

data_s *foo = data; 
foo->LightSwtich1 = FALSE; 
foo->Brightness = 7; 
//... 

Lösung 2: Verwenden Bitmasken:

data[0] |= 0x02; 
data[0] = (data[0] & 0x0F) | ((7 << 4) & 0xF0) 
//... 

Nun, ich weiß, Bitfelder sind Compiler abhängig und sind nicht so tragbar. Deshalb wird die Lösung 2 oft bevorzugt. Trotzdem sieht Lösung 2 viel komplizierter aus und ist schwerer zu lesen. Darüber hinaus wäre es viel Arbeit, wenn der zugeordnete Speicher mehr als acht Bytes hätte.

Muss ich wirklich die Lösung2? Oder ich könnte die #pragma reverse_bitfields on Direktive verwenden, um die Portabilität der Lösung 1 zu verbessern? Kann ich Lösung 1 verwenden, wenn der Code nur für ein Ziel mit einem Cross-Compiler erstellt wird?

Also meine Frage ist: Wie sollte ich auf die richtigen Bits zugreifen?

+0

Bitfelder sind tragbar und Teil des C-Standards. Es ist eine Frage der Code Lesbarkeit und Gewohnheiten: in meinem Fall bevorzuge ich Bitmasken, aber viele Leute bevorzugen Bitfileds. – LPs

+0

MISRA verwendet, um die Verwendung von Bitfeldern zu sperren, ich weiß nicht, ob es immer noch tut. – Toby

+0

Sie können Lösung 2 mit #define-Makros deutlich lesbarer aussehen lassen. Sie würden mit dem hässlichen unlesbaren Zeug an nur einem Ort enden, was den zusätzlichen Vorteil hat, die Menge an Arbeit zu reduzieren, die benötigt wird, um in der Zukunft Änderungen vorzunehmen. –

Antwort

3

Der Grad, zu dem Bitfelder Compiler-abhängig sind, wurde etwas übertrieben. Sie werden meistens komisch, wenn Sie sie auf eine seltsame Weise benutzen.

In Ihrem Beispiel sind alle Felder vorzeichenlos und haben den gleichen Speichertyp, keiner von ihnen überschreitet eine Speichergrenze, und es gibt keine unbenutzten Bits. Es gibt das Problem, Bits zu bestellen (wie Sie gesehen haben), aber in den letzten Jahren hat sich jeder auf die gleiche Reihenfolge festgelegt. Soweit ich weiß, wird kein aktueller Compiler irgendetwas produzieren, das nicht mit den IO-Daten kompatibel ist, die Sie erhalten.

Verwandte Themen