Found nasty bug with WizNet using rxUDP
ags
Posts: 386
I had the misfortune of apparently being the first person to have just the right value(s) stored in just the right memory address to take advantage of an undocumented feature in the W5100 (v0.8) rxUDP() method. It results in overwriting all of hub RAM below a VAR (e.g. stack). I'm in the process of getting it uploaded to the respository, but it's just a one-line change if anyone is having unexplainable crashes and is using the rxUDP() method. I looked at the rest of the code for similar problems (most notably txUDP, rxTCP & txTCP) but don't believe they are affected. Here's the fix:
You can verify this by setting pcktsize := $FFFFFFFF instead of 0; this mimics what could happen (and did happen to me) if you were just lucky enough to have previously written to the high-word at that location on the stack. You can also verify that no other locals need initialization by setting them all to $FFFFFFFF (except pcktsize). This is because either the high-word is never read, or the entire long is always bitwise-ANDed with a low-word mask value.
Good luck, happy spinning.
Al
'*************************************** PUB rxUDP(_socket, _dataPtr) | temp0, RSR, pcktsize, pcktptr, pcktoffset, pcktstart, rolloverpoint '*************************************** '' Receive UDP data on the specified socket. Most of the heavy lifting of receiving data is handled by the ASM routine, '' but for effeciency in coding the SPIN routine walks through the process of receiving data such as verifying and manipulating '' the various register. This routine could be completely coded in ASM for faster operation. '' '' The receive routine brings over only 1 packet of UDP data at a time. The packet is based on the size of data read in the packet '' header and not the receive register size. '' '' params: _socket is a value of 0 to 3 - only four sockets on the W5100 '' _dataPtr is a pointer to the byte array to be written to in HUBRAM (use the @ in front of the byte variable) '' return: Non-zero value indicating bytes read from W5100 or zero if no data is read '' '' The data returned is the complete packet as provided by the W5100. This means the following: '' data[0]..[3] is the source IP address, data[4],[5] is the source port, data[6],[7] is the payload size and data[8] starts the payload pcktsize := 0 'This local (a long) must be initialized because only the two ' low bytes are ever written, but the full (long) value is read. 'Note pcktptr is OK since it is always bitwise-ANDed with a ' 2-byte mask when read 'Bug fix 01-19-2011 by ags
You can verify this by setting pcktsize := $FFFFFFFF instead of 0; this mimics what could happen (and did happen to me) if you were just lucky enough to have previously written to the high-word at that location on the stack. You can also verify that no other locals need initialization by setting them all to $FFFFFFFF (except pcktsize). This is because either the high-word is never read, or the entire long is always bitwise-ANDed with a low-word mask value.
Good luck, happy spinning.
Al
Comments
From my studying the code (not executing anything) I agree with what you are saying and can see how this causes trouble with a counting variable in the ASM. I glanced at the other variables and don't see this to be a problem as you so correctly stated because they aren't used in the ASM or have a mask applied to them.
I'd like this see this fix look like this:
I also see that a prior bug fix was improperly copied from the SPI to the IND because the code wasn't uniform. DOH! I need to ensure these four section of code are identical.