Fri 28 Feb 2003 10:27:45 AM UTC, original submission:
Any processor with alignment error check turned on will suffer this issue.
Lets say we want to send two packets:
Packet1 : Size 45 bytes
Packet2 : Size 300 bytes
netconn_write() is called twice consecutively for sending the above 2 packets. The netconn->pcb.tcp->snd_buf sets the buffer size limit for data to be packed together for sending.
Packet1 Packet2
-------- ----------------------------
| 45 | | 300 |
-------- ----------------------------
|
|
| After 2 consecutive netconn_write() calls
|
V
buffer (256 bytes) buffer (256
bytes)
_______|________________ __|_____
( ) (
-------- ----------------- ----------
| 45 + 211 | | 89 |
-------- ----------------- ----------
The second packets 2nd half (89 byte data - packet data starting on an odd byte boundary) when sent to lwip_chksum() routine, which does a 16 bit access causes Alignment fault (memory access exception). This holds true on all processor platforms that dont allow unaligned memory access.
Another explanation (to give a better picture):
This issue happens well in advance within the LwIP code.
In an LwIP application, netconn_accept() returns 'netconn' structure upon receiving new application data packet <HTTP> on a particular port.
The netconn->pcb.tcp->snd_buf variable is equal to 256 (no idea who sets this number). Following this, netconn_write() is called (to send out packets) & the value of netconn->pcb.tcp->snd_buf gradually reduces by the amount of data sent out (in bytes). As I understand netconn->pcb.tcp->snd_buf sets the limit of data sent in an instance within the loop inside netconn_write().
Now lets consider that the application has the following data packets to be sent out.
PACK1 : Size = 45 bytes long, &PACK1[0] = 0x00001000
PACK2 : Size = 300 bytes long, &PACK2[0] = 0x00002000
After the 1st netconn_write( .. PACK1 .. ), netconn->pcb.tcp->snd_buf = 256-45 = 211 <after PACK1 is processed>.
Then the application sends the second packet by calling netconn_write( .. PACK2 .. ).
Within netconn_write()s loop, 211 bytes of PACK2 is 1st processed & then it tries to process the remaining data (data staring at PACK2[211]).
This data packet starting at PACK2[211] is eventually sent to lwip_chksum(), which access data within packet as half-words (16 bits). The very 1st access will result in doing a 16-bit access at address (0x2000 + 211) <- this address is not half-word aligned, so the processor aborts.
This was evident when running Adam's sample code (modified version) on a MIPS 4Kc (32 bit platform) processor board.
|