www.mikrocontroller.net

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


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
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

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:
uint16_t 0x7002

.headerlen = 7
.res = 0
.flags = 2

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

Danke im Voraus
lg Martin

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Klaus,

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

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie bringst du denn die Werte in die struct rein?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 Deppen, ein Gedanke...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Bitte, Alter vor Schönheit!

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.