PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : bitfelder



dominik699
04.09.2010, 22:32
hallo,

möchte einen kleinen netzwerk stack schreiben.

dabei sieht der header wie folgt aus:

8bit adresse
2bit addressentyp
4bit messagetype
1bit ack
1bit nack

habe den hader also in eimen struct mit bitfeldern angelegt:



typdef struct
{
uint8_t adresse;
uint8_t adresstype:2;
uint8_t messagetype:4;
uint8_t ack:1;
uint8_t nack:1;
}header_t;



jetzt will ich das ganze versenden. zuerst die 8 bit adresse und dann die 8 bit restlichen header (ack, nack, messagetype....). gibt es eine möglichkeit auf die gesamten zweiten 8 bit zuzugreifen.

soweit ich das verstanden habe, ist nicht garantierte, wie und wo der compiler die bitfelder ablegt. somit hat es mit pointern auch keinen sinn. oder verstehe ich da etwas falsch. das ganze sollte noch halbwegs schnell laufen, da recht viele pakete versendet werden.

mfg

dominik

Felix G
05.09.2010, 01:17
Bei solchen Problemen heisst das Zauberwort: "union"

Hier mal ein Beispiel:

typedef union
{
uint16_t Raw;

struct
{
uint16_t Command : 6;
uint16_t Address : 5;
uint16_t Toggle : 1;
uint16_t Field : 1;
uint16_t Start : 1;
} Structured;
} type_RC5_Frame;

In diesem Fall kann auf den gleichen Speicherbereich wahlweise per "Structured" als Bitfeld, oder aber per "Raw" an einem Stück zugegriffen werden

fumir
22.02.2011, 06:56
Bei solchen Problemen heisst das Zauberwort: "union"

Hier mal ein Beispiel:

typedef union
{
uint16_t Raw;

struct
{
uint16_t Command : 6;
uint16_t Address : 5;
uint16_t Toggle : 1;
uint16_t Field : 1;
uint16_t Start : 1;
} Structured;
} type_RC5_Frame;

In diesem Fall kann auf den gleichen Speicherbereich wahlweise per "Structured" als Bitfeld, oder aber per "Raw" an einem Stück zugegriffen werdenbei einem struct von bitfeldern kann der compiler im prinzip jedes bitfeld in einem eigenen word oder an beliebiger stelle speichern. greift man dann über ein union darauf zu, hat man keine controlle über die position der bitfelder. union garantiert nur, dass jeweils platz vorhanden ist für die daten die man ablegen will. dabei hat man keine garantie für die position.

das kann natürlich trotzdem funktionieren, da compiler ja kein interesse daran haben, die dinge unnötig kompliziert zu machen. aber verlassen würde ich mich darauf nicht :-)

ich würde mir auf jeden fall mal die optimierungsoptionen des compilers anschauen.

sicherer ist es vermutlich, über eigene masken auf bitfelder in einem uint16_t zuzugreifen.

Felix G
22.02.2011, 08:43
Naja, sagen wir mal es kann nicht schaden den vom Compiler erzeugten Code zu überprüfen. Mein Beispiel wird vom AVR-GCC jedenfalls sinnvoll übersetzt, obwohl er es theoretisch auch anders machen dürfte.

Das Verhalten, das der C99 Standard für Bitfelder vorschreibt, ist außerdem auf diese Art am leichtesten zu erreichen. Daher ist es wahrscheinlich, daß derartige Konstrukte von allen Compilern korrekt übersetzt werden.