Hello everybody.
Once again, I'm sorry if I'm asking something too obvious. I have defined some structures in C to access the different fields of an Ethernet frame in a more elegant way than using simple byte arrays. The structure is:
typedef struct { u8 DestMACAddr[6]; u8 SrcMACAddr[6]; u16 LengthType; union { struct { u16 QTagCtlInfo; u16 LengthType; u8 Payload[1500]; u8 ALIGN[2]; // So that the data type is 32-bit aligned } TAGGED; u8 Payload[1500]; } Content; } EthernetFrameType;
, which works pretty much OK.
Now, to process the ARP frames in a similar way, I define the following type:
// ARP Protocol Payload Type typedef struct { u16 HwType; u16 ProtType; u16 HwProtLengths; u16 Operation; u8 SrcMAC[6]; u32 SrcIP; u8 DestMAC[6]; u32 DestIP; } ARPPayloadType;
Then I use a pointer of type ARPPayloadType to access the Payload field in the EthernetFrame:
EthernetFrameType frame; ARPPayloadType *arp; arp = (ARPPayloadType *)frame.Content.Payload; if (arp->Operation == 0x0100) { //It's a request } else if (arp->Operation == 0x0200) { //It's a response }
I use these data types in the tx. and rx. buffers for the Ethernet controller.
My problem is that it is not working. For some reason, the compiler reserves 8 bytes for the MAC address fields in the ARP type definition, but assigns the others fields their expected sizes. I mean: I have checked the address where each field is stored, and all of them are where expected, except for the SrcMAC and DestMAC fields within the ARPPayloadType structure, which are both 8 bytes long (thus moving the SrcIP and DestIP fields two bytes forward their expected positions).
I thought that maybe this had something to do with word alignment,but the buffers are 32 bits aligned, and their size is adjusted so that two contiguous frames (such as those in an array) do not 'break' that alignment (that's the purpose of the "ALIGN" field).
I know that we are not suppossed to have such a precise control on the data storage, and that leaving or not "blanks" in the middle of two suppossedly contigous data containers is a decission of the compiler, but I don't understand why it happens only in the ARP part, and only in that fields, and not in the Ethernet header part, which also has two MAC address fields (the ones which are neither 16-bit nor 32-bit aligned).
So, do you have any clues on why this is so? Any workarounds? Should I read the data using a byte array and stop messing things up?
Thank you very much for you answers.
Lacking any kind of packing attribute, structure members will be aligned on their natural boundaries. ARPPayloadType.SrcIP requires two padding bytes after '.SrcMAC[] for proper alignment.
Use some kind of structure packing attribute or change the SrcIP and DestIP members to:
/* ... */ u8 SrcIP[4]; /* ... */ u8 DestIP[4];
Thanks a million! I imagined it was something like that but I didn't actually know how this works.
Best regards, Ruben
View all questions in Keil forum