Forum: Mikrocontroller und Digitale Elektronik Keil MDK: Alignment bei Bitfields


von Martin (Gast)


Lesenswert?

Hallo an alle,

ich schreibe gerade einen TCP/IP Stack für einen ARM. Ich benutze die 
Keil MDK in Version 3.5. Die Daten werden dabei mit Strukturen 
verwaltet.
1
typedef __packed struct  
2
{
3
        uint16_t srcPort;
4
        uint16_t dstPort;
5
        uint32_t seq;
6
        uint32_t ack;
7
        uint16 headerlen      : 4;
8
        uint16 res            : 6;
9
        uint16 flags          : 6;
10
        uint16_t windowSize;
11
        uint16_t checksum;
12
        uint16_t urgentPtr;
13
}
14
TCP_Header

Die Daten bis zum Bitfeld stimmen. Auch die Variablen danach haben die 
richtigen Werte. Nur die Variablen des Bitfeldes stimmen nicht. Daher 
vermute ich ein Alignment Problem.

So sollte es ausschen:
1
uint16_t 0x7002
2
3
.headerlen = 7
4
.res = 0
5
.flags = 2

Leider stimmen die Werte nicht. Wie kann ich Keil sagen, das Alignment 
anzupassen?

Danke im Voraus
lg Martin

von Klaus W. (mfgkw)


Lesenswert?

> Leider stimmen die Werte nicht.

Bei so einer tollen Fehlerbeschreibung kommen bestimmt tolle Antworten.

Ok, hier die erste: wer sagt denn, daß headerlen in den oberen
Bits untergebracht wird und flags in den unteren, und nicht einfach
umgedreht?

von Martin (Gast)


Lesenswert?

Hallo Klaus,

Folgende Wert habe ich: headerlen = 0, res = 39d, flags = 0.
So ganz verstehe ich das Bitmuster jedoch nicht.

von Helmut L. (helmi1)


Lesenswert?

Versuchs mal mit __packed


Also so:

typedef __packed struct
{
        uint16_t srcPort;
        uint16_t dstPort;
        uint32_t seq;
        uint32_t ack;
        uint16 headerlen      : 4;
        uint16 res            : 6;
        uint16 flags          : 6;
        uint16_t windowSize;
        uint16_t checksum;
        uint16_t urgentPtr;
}
TCP_Header __packed

Gruss Helmi

von Martin (Gast)


Lesenswert?

Hallo Helmut,

__packed benutze ich ja bereits. Siehe obiges Snippet. Bei der 
Deklaration des Pointers hilft es auch nicht, wobei ich denke, dass das 
__packet hier nicht sinnvoll ist, oder?

lg Martin

von Klaus W. (mfgkw)


Lesenswert?

39d ist doch binär 100111.
Das sind oben mit 10 die 2d, die du in flags haben willst (0010),
darunter dann mit 0111 die 7d, die nach headerlen sollen.

von Klaus W. (mfgkw)


Lesenswert?

wie bringst du denn die Werte in die struct rein?

von Martin (Gast)


Lesenswert?

Die Werte kommen per Netzwerk rein. Ein TCP_Header Zeiger zeigt mit 
einem Offset auf den Empfangspuffer. Der Wert 0x7002 für das 16-Bit Wort 
stimmt.

Die Aufteilung so habe ich schon gesehen, verstehe jedoch nicht warum 
diese so zustande kommt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

soll: 0111 0000  0000 0010
ist:  0000 0010  0111 0000
Fällt dir was auf?
Tausch die Bytes mal über Kreuz...
Little- oder Big-Endian-Problem?

von Klaus W. (mfgkw)


Lesenswert?

mit welcher Byte order werden die Werte gesendet?
Und mit welcher beim Empfänger interpretiert?
Vermutlich nicht beides gleich...

von Klaus W. (mfgkw)


Lesenswert?

2 Deppen, ein Gedanke...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> 2 Deppen, ein Gedanke...
Aber einer war schneller  ;-)

von Klaus W. (mfgkw)


Lesenswert?

Die anderen Werte in der Struct sind viellicht auch nicht viel besser?

von Klaus W. (mfgkw)


Lesenswert?

Lothar Miller schrieb:
> Klaus Wachtler schrieb:
>> 2 Deppen, ein Gedanke...
> Aber einer war schneller  ;-)

Bitte, Alter vor Schönheit!

von Martin (Gast)


Lesenswert?

Hallo,

Ich dachte der Endian-Effekt tritt erst auf, wenn ich Variablen größer 1 
Byte habe.

Gibt es eine Möglichkeit, die Endian bei einem Bitfeld zu ändern??

Die anderen Werte stimmen. Bzw rechne ich bereits auf Little Endian um.

lg Martin

von Klaus W. (mfgkw)


Lesenswert?

Martin schrieb:
> Hallo,
>
> Ich dachte der Endian-Effekt tritt erst auf, wenn ich Variablen größer 1
> Byte habe.

Hast du doch: die 3 Bitfelder sind zusammen 16 Bit, also mehr als
eines. Und damit wird es gedreht...

>
> Gibt es eine Möglichkeit, die Endian bei einem Bitfeld zu ändern??

Nein.

>
> Die anderen Werte stimmen. Bzw rechne ich bereits auf Little Endian um.

Na dann...

>
> lg Martin

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.