#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
/Daniel
-----Original Message-----
From: owner-u...@sics.se [mailto:owner-u...@sics.se] On Behalf
Of Willi Schulte
Sent: den 5 mars 2007 15:30
To: uip-...@sics.se
Subject: [uip-users] Byte ordering problem with ARM7
Hi all,
I try to port uIP 1.0 to the LC2132. First of all I had trouble
with the uIP Log Message "ip: Invalid version or header length".
Obviously there is a problem with the linker. Mr. McKenney had the
same problems and could give me some hints to fix it
(struct ... __attribute__((packed));)
Now I had the next problem: ARP does not work. With debug-prints
I found out that there is an endian problem.
The quick fix in main() was:
---------------------------------------------------------------------
// uip_ipaddr(ipaddr, 192,168,1,160); // looks good but does not work
uip_ipaddr(ipaddr, 168,192,160,1); // looks crazy but ARP works
uip_sethostaddr(ipaddr);
// ... the same change for the netmask and ARP and PING works!
---------------------------------------------------------------------
I can't believe that this is the "solution". Something else
must be wrong here. Has anyone an idea what had happened?
I am using GNU-C with KEIL-IDE and the LPC2132 in "little edian"
mode, also in "uipopt.h".
Thanks a lot in advance,
Willi
I had similar problems, although not in the same piece of code. It had
more to do with misaligned access than with endianess. IIRC, on the
LPC213x (and maybe all ARM's, not sure), misaligned accesses to 16-bit
values (ie. most IP addresses in uIP) can cause a read from the 32-bit
aligned address followed by a bit rotate to get the correct bytes. Also,
if you are attempting to typecast a misaligned buffer to a structure make
sure the structure is defined as "packed".
One fix that I had to use was to define the Link Layer Header length to a
multiple of 4 to ensure that the uIP buffer was properly aligned and thus
the IP headers were properly aligned as well.
One other thing I noticed when sifting through the assembler output was
that the GCC optimizer took two adjacent 16-bit compares such as:
u16_t x[2], y[2]
/* ... */
if ((x[0] == y[0]) && (x[1] == y[1]))
{
/* Do something interesting */
}
and optimized into something like this:
u32_t X, Y
/* ... */
if (X == Y)
{
/* Do something interesting */
}
The above is only correct if both x[] and y[] are aligned on a 32-bit
boundary which may not be the case if they are part of a packed or
misaligned structure.
Please note: The above example is for illustration only. It is what I
remember of a simple hand "decompilation" of some generated assembler code
from several months ago. I noticed this behaviour on structures that were
not defined with a specific alignment or packed attribute, so it is quite
possible that those attributes might prevent such optimization.
Hope this helps.
Patrick
Willi
As Patrick pointed out, it's more like an alignment problem, on arm
that's a heavy issue. On arm7, an unaligned access doesn't generate a
trap, instead, it's accepted on a very specific arm way that internally
rotates the bits not in the way one would expect. The compiler assumes
you know what you're doing, and will not try to cope with unaligned
accesses unless the data type (or the attributes, such as packed)
implies that.
I did a fresh port of uip 1.0 to philips lpc series of arm7-based 甥s,
all I had to do was to put attribute aligned on the uip buffer (uip_buf
variable if I recall it correctly), but that's because I based my port
on a ppp driver, therefore I had no arp around. With arp, the driver
fills the first 14 bytes with the arp header and the whole thing
misaligns. A possible solution would be to change UIP_BUF (IIRC) macro
to point to index 2 instead of 0 of the matrix, and make sure the
ethernet driver code has that gap. That would wast 2 bytes of the
buffer, but would relieve from the need to sparsely put packed attribute
tags around.
There's a long term debate with some people defending that many of the
theoretical benefits of an architecture requiring aligned access ends up
being purely fictional on the real world due to the complexity it
introduces on higher level code, but for now we have to cope with that.
Just in time: another change I had to do was on the dns resolver code.
If you plan to do that, it also has misalignments. I can read the code
and try to remember where, if that's relevant to you or somebody else...
- Alexandre
I think you are right that I have alignment problems with uIP Code and
the ARM/LPC-architecture.
How holy is the code of uIP? I first planned to change nothing inside
to have compatibility to later versions ...
My feeling is that the ARM7 does not fits really good to uIP because
it can not use the 32-bit-power. lwIP should be better but the LPC2132
has not enough SRAM inside.
By the way:
PING Answering needs 62 ms. That's a lot. It depends on the uIP
concept, doesn't it?
Regards,
At this moment I'm running uIP on a Windows PC as a test environment. The
ping time depends on time interval between calling the uIP run loop. I have
a 10ms delay between calls and I see an average delay of about 10ms between
pin responses.
Nico Coesel
-----Oorspronkelijk bericht-----
Van: owner-u...@sics.se [mailto:owner-u...@sics.se] Namens Willi
Schulte
Verzonden: dinsdag 6 maart 2007 10:02
Aan: uip-...@sics.se
Onderwerp: Re: [uip-users] Byte ordering problem with ARM7
/Daniel
-----Original Message-----
From: owner-u...@sics.se [mailto:owner-u...@sics.se] On Behalf Of Willi Schulte
I had some debug-prints. Changing that the ping time goes down to 4 ms!
Willi