Forum: Compiler & IDEs [arm-elf-gcc] Über struct auf byte-Array zugreifen.


von Laurenz K. (gimmebottles)


Lesenswert?

Hallo,

ich bin gerade an der Portierung von uIP auf einen LPC2387 und stehe vor 
einem Problem.

uIP kopiert empfangene Daten in einem Array uint8_t uip_buf[LEN]. In der 
main-Schleife wird dann folgendermaßen auf dieses Array zugegriffen, um 
die Art des empfangenen Pakets zu bestimmen:
1
if((uint16_t)BUF->type == htons(UIP_ETHTYPE_IP))

wobei BUF so definiert ist:
1
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])

Schließlich noch uip_eth_hdr:
1
struct uip_eth_hdr {
2
  struct uip_eth_addr dest;
3
  struct uip_eth_addr src;
4
  u16_t type;
5
};

uip_eth_addr sind jeweils 6 uint6_t Werte für die MAC-Adressen.

Wenn im uip_buf folgendes enthalten ist:
1
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
2
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
3
0x08,0x06

Dann gehe ich davon aus, dass BUF->type mir 0x0806 liefert. Das tut es 
aber nicht, BUF->type gibt mir nur 0x08 zurück, das zweite byte wird 
anscheinend nicht gelesen.

Kommt jemand dieses Problem bekannt vor?

Vielen Dank,

Laurenz

von Dr. Sommer (Gast)


Lesenswert?

Wenn schon hätte ich 0x0608 erwartet, wegen Little Endian. Verifiziere 
doch mal im Debugger, dass die Adresse von BUF->type an die richtige 
Stelle im Speicher verweist.

von (prx) A. K. (prx)


Lesenswert?

Wenn der Ethernet-Frame word-aligned ist, dann sind die IP-Adressen 
misaligned. Man kann dann mit einem ARM7 nicht direkt auf das Wort 
zugreifen. Was ausserdem die falsche Bytereihenfolge hat.

Manche legen den Ethernet-Frame so in den Speicher, dass er passend 
misaligned ist, dafür aber der IP Header word-aligned ist.

In jedem Fall muss für Zugriffe >Byte ein Alignment sichergestellt sein. 
Bei Byte-Arrays ist das von Haus aus nicht gewährleistet.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Dr. Sommer schrieb:
> Wenn schon hätte ich 0x0608 erwartet, wegen Little Endian.

Wird er auch kriegen, wenn richtig gemacht. Weshalb er mit htons(0x0806) 
vergleicht. 08 kriegt er, weil beim ARM7 beim misaligned load zwar immer 
das adressierte Byte in Bits 0..7 vom Register landet, aber der Rest 
nicht stimmt.

von Laurenz K. (gimmebottles)


Lesenswert?

Um auf die richtigen Daten (0x0806) zuzugreifen, müsste BUF->type ja auf 
uip_buf + 12 verweisen, er verweißt aber auf uip_buf + 16, wo zufällig 
auch eine 0x08 liegt.

von (prx) A. K. (prx)


Lesenswert?

Laurenz K. schrieb:
> Um auf die richtigen Daten (0x0806) zuzugreifen, müsste BUF->type ja auf
> uip_buf + 12 verweisen, er verweißt aber auf uip_buf + 16

Woran erkennst du das? Wenn uip_eth_addr aus 6 uint8_t besteht, dann 
liegt type an 12.

von Laurenz K. (gimmebottles)


Lesenswert?

A. K. schrieb:
> Laurenz K. schrieb:
>> Um auf die richtigen Daten (0x0806) zuzugreifen, müsste BUF->type ja auf
>> uip_buf + 12 verweisen, er verweißt aber auf uip_buf + 16
>
> Woran erkennst du das? Wenn uip_eth_addr aus 6 uint8_t besteht, dann
> liegt type an 12.

Wenn ich
1
test = &BUF->type;
einfüge, sehe ich im Debugger dass test auf uip_buf + 16 verweißt.

von (prx) A. K. (prx)


Lesenswert?

Dann stimmt was an uip_eth_addr nicht. Eine struct aus 6 Bytes sollte 
nur 6 Bytes gross sein und keine Alignment-Einschränkungen haben.

: Bearbeitet durch User
von Laurenz K. (gimmebottles)


Lesenswert?

A. K. schrieb:
> Dann stimmt was an uip_eth_addr nicht. Eine struct aus 6 Bytes sollte
> nur 6 Bytes gross sein und keine Alignment-Einschränkungen haben.

Ja, ein __attribute__((packed)) wirkt da Wunder :D

Scheint jetzt zu laufen, mal sehen was noch kommt.

: Bearbeitet durch User
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.