lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Struct packing/alignment problems


From: Timmy Brolin
Subject: Re: [lwip-users] Struct packing/alignment problems
Date: Mon, 26 Apr 2004 22:45:17 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)

Did you replace the 32bit IP and TCP fields with two 16bit fields?

Timmy

Chris Jones wrote:

I have recently completed revisions to the LWIP code to port it to a
TI C55 DSP. I am using a SLIP interface to my target and therefore did
not port the ethernet layer. The lessons learned, however, can be applied
to help solve the structure packing / byte alignment problems of DSP
platforms.

The problems I had to address were as follows ...

- The C55 is a 16 bit DSP that implements a char as a 16 bit value.
The u8_t fields in the structure definitions for IP and TCP headers
expanded to 16 bits and no longer overlayed the input buffer correctly.

- Throughout the code, pointers of type u8_t * are used to adjust
addresses. Since the DSP doesn't do byte addressing, these all needed to be
fixed.



I solved these problems by making these mods to the code ...

- I redefined the IP and TCP headers in terms of 16 bit integers and
use macros in the code to extract the values. Some of this work had
already been started. The IP header was nearly complete but the TCP
header needed work. This could easily be extended to 32 bit integers.

- I changed the dynamic memory management code to work with words
instead of bytes. This allowed me to eliminate the use of byte pointers
and eliminate most of the memory alignment macros used in the code.

- I couldn't use memcpy() to move data into the pbuf buffer because
it works with 16 bit characters. Therefore, I explicitly copied each
byte into the pbuf in big endian order. Although this sounds like a
lot of overhead, it had the huge benefit of being able to eliminate all
uses of the byte swapping routines ntohl(), ntohs(), etc. each time a
data member is accessed. I do the byte swaping once and only once when
the pbuf is filled.

- replaced sizeof() operator with SIZEOF_WORDS() and SIZEOF_BYTES()

- replace memset() and memcpy macros with word based equivalents as
necessary.


My changes weren't made to explicitly handle the structure alignment
problems. I was working with SLIP and didn't have to worry about the
14 byte ethernet header.

Using a previous poster's suggestion, it would seem reasonable to skip
two bytes at the end of the ethernet header to make sure the IP and
TCP headers are aligned correctly.


I have posted the modified code on our company website.

There are also PDF files which show differences for some selected modules.

http://www.engeniumtech.com/lwip/lwip_dsp.htm



-Chris Jones

Engenium Technologies



-----Original Message-----
From: address@hidden
[mailto:address@hidden
Behalf Of Timmy Brolin
Sent: Monday, April 26, 2004 5:34 AM
To: Mailing list for lwIP users
Subject: Re: [lwip-users] Struct packing/alignment problems


That's alot of work you have done there.
A decent solution to this alignment problem is really needed, because as
it is now, lwip is incompatible with most 32bit embedded CPUs.(!!) (Such
as ARM, TI DSPs, ...)
I have been thinking some more.. Four u8_t is actually not very optimal,
two u16_t might be a better solution. Two u16_t fields equals about the
same performance as a unaligned u32_t even on systems that do support
unaligned memory accesses, so replacing all 32 bit fields with two u16_t
should work fine for all architectures.
(A 32bit unaligned memory read usually results in two memory read cycles)

I have also been considering a second approach where I add a 16bit pad
to the very beginning of the ethernet header. No data must be
rearranged, the packet is simply written to offset 2 into the pbuf. This
way all 32bit fields become aligned except for the dipaddr in the ARP
header. This field can be substituted with two u16_t, and everything is
solved.
This solution should actually increase performance slightly, even on
32bit systems that do support unaligned memory accesses. The only bad
thing is that two bytes per packet are wasted.

When the alignment problem is solved, we can get rid of all thoose ugly
PACK_STRUCT makros, because they are only needed for unaligned structs.

Timmy Brolin

Mountifield, Tony wrote:

I considered solving the problem by changing the ip_addr struct from:
struct ip_addr {
u32_t addr;
}
To something like:
struct ip_addr {
u8_t addr0;
u8_t addr1;
u8_t addr2;
u8_t addr3;
}

But I found that this struct is used in tons of places.
That's alot of code to
rewrite..
Have anyone solved this problem without introducing padding?


Yes, I had to use a similar approach to what you suggested:

struct ip_addr {
u8_t addrb[4];
}

I changed the name to ensure the compiler would catch all occurrences.

I then used macros to access the address. When copying, I used structure
copy, i.e. instead of "p->addr = x->y.addr;" I did "*p = x->y;". I defined
htonlb() and ntohlb() functions too.
A lot of the required changes are actually in LWIP_DEBUGF statements.

The next thing I found was that similar changes were needed for the seqno
and ackno in the TCP header, which are also unaligned, and so need
redefinition as u8_t arrays. It is then necessary to be careful about byte
order. Instead of rewriting the header in the received buffer, I left the
seqno and ackno in network byte order in the header, but transformed to
native order when copying to local variables.
I have hesitated to submit my changes yet, because there are still a few
kludges and also I haven't yet ensured portability back to CPUs and
compilers that don't need all this trickery. Also because I've been doing it
as paid work.
Cheers,
Tony


***************************************************************************
********
This email, its content and any attachments is PRIVATE AND
CONFIDENTIAL to TANDBERG Television. If received in error please
notify the sender and destroy the original message and attachments.

www.tandbergtv.com
***************************************************************************
********

_______________________________________________
lwip-users mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/lwip-users








_______________________________________________
lwip-users mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/lwip-users



_______________________________________________
lwip-users mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/lwip-users







reply via email to

[Prev in Thread] Current Thread [Next in Thread]