|
From: | Timmy Brolin |
Subject: | Re: [lwip-users] Struct packing/alignment problems |
Date: | Tue, 27 Apr 2004 01:58:22 +0200 |
User-agent: | Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) |
Chris Jones wrote:
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.
Yes. I'am one of thoose. :)I find lwip very suitable for DSP applications. High performance no-copy implementation, BSD style license, and straightforward API.
Yes, the 32bit fields in the IP and TCP headers can be easily aligned by adding 16bits of padding in the ethernet header. Problem is, you don't want to rearrange the incomming packet data, sice that would take a big hit on performance. You want to be able to DMA the packet directly from the ethernet interface into the main memory and be done with it. Putting a 16bit pad in the very beginning of the Ethernet header is probably the solution to this. The ARP header is a bit more troublesome. Fourtunately, it is not as heavily used as TCP/IP packets, so a special case solution could be acceptable.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.
It is not that hard to patch it up to work, no. It is a little harder to make it work without ugly patches such as data rearrangement and decreased performance. The ideal thing would be to find the optimal solution and integrate it into lwip. I got lwip 0.7.1 working on my DSP a few days ago by padding both the ethernet header and the ARP header. Performance is acceptable, but I will need to clean it up eventually.I implemented some of what needs to be done and found it fairly straight-forward.
Timmy
-----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 tobefixed. 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 structurecopy, 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 seqnoand 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 fewkludges 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 doingitas 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 _______________________________________________ lwip-users mailing list address@hidden http://mail.gnu.org/mailman/listinfo/lwip-users
[Prev in Thread] | Current Thread | [Next in Thread] |