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: Chris Jones
Subject: RE: [lwip-users] Struct packing/alignment problems
Date: Mon, 26 Apr 2004 17:08:23 -0400

No, the C55 has a 32 bit integer type, it is just not optimal.

I left the fields as 16 bit integers because most of the work for the
IP header was already done and I was trying to minimize changes.

I think I was able to write my code in such a way that it could easily be
extended to a 32 bit word, but I never actually tried it.

-Chris


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


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
>
>
>
>



_______________________________________________
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]