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 19:02:47 -0400

I know from searching the archives there is a sizable community
that would like to use LWIP on one of several 32 bit DSP platforms.

Both the structure packing problems and the DSP port problems could
be solved by allocating memory in 32 bit chunks and aligning the
Ethernet, IP and TCP headers and the data on 32 bit boundaries
with padding if necessary.

I implemented some of what needs to be done and found it fairly
straight-forward.

-Chris



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


The 32bit fields are the cause of the alignment/packing problems.
Replacing them with 16bit fields would solve this problem.

Timmy

Chris Jones wrote:

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