I will start with the part that you probably care the most about. Once I got your sample to startup after being built with gcc, I got a crash in Recv_Data() as it tried to free a data buffer from the queue. This is caused by the fact that there are allocations taking place in Hook_UDPv4() which is called from within the Ethernet ISR while frees are happening in the main code. This will easily lead to heap corruption and would be more likely to take place the more often you receive UDP packets. Removing the calls to read the data would get rid of the main line heap free calls so that would protect the heap from corruption as well. The mbedNet code should be rewritten to remove the dynamic memory allocations from within the ISR.
Program received signal SIGSEGV, Segmentation fault.
0x0000cb2a in _free_r () at EncoderDefs.h:8
8 DigitalIn EncPairB[8] = { ( p12 ), ( p14 ), ( p16 ), ( p18 ), ( p20 ), ( p22 ), ( p24 ), ( p26 ) };
(gdb) bt
#0 0x0000cb2a in _free_r () at EncoderDefs.h:8
#1 0x00004ece in Recv_Data (entry=0x10002de8, data=0x10000b84 "@0 \020\001", length=1024) at mbedNet/Sockets.cpp:244
#2 0x00005858 in Sockets_RecvFrom (socket=0, data=0x10000b84 "@0 \020\001", length=1024, flags=0,
remoteAddr=0x10002bdc, addrLen=0x10007f60) at mbedNet/Sockets.cpp:567
#3 0x000013f0 in main () at Encoder_Handler.cpp:425
You can either try refactoring mbedNet to not require any dynamic memory allocations from the ISR (pre-allocate all of the buffers when the socket is created for example and then just marking them as free or not) or try switching to EthernetIf and we can try debugging what problems it has. It should be different since this particular queuing code looks like it is particular to mbedNet.
Now for me to ramble on about other things that I hit while looking at this code that you probably don't care about. The first is that I couldn't even get the code to barely start after the initial port without it crashing almost immediately in the ISR. It would crash on this line of ENET_IRQHandler():
LPC_EMAC->IntClear = status;
At first when I went to dump the LPC_EMAC registers in the debugger, I just got a bunch of 0xdeadabba values. I thought this was caused by some missing code to enable the Ethernet peripheral or properly set its clock. After much debugging, I determined that it didn't start to happen until the peripheral was actually powered up and it was actually a bug in my debug monitor. It turns out that those registers can't be read a byte at a time and that is what the monitor tries to do based on the protocol spec. I do see that there is a way for me to know that the user is actually accessing them a word at a time and do the right thing from the monitor so I will need to make that modification.
So now what was leading to the crash if the Ethernet peripheral was powered up correctly? It turns out that the non-optimized code generated by GCC for the above line is:
0x00006ddc <+16>: mov.w r3, #1342177280 ; 0x50000000
=> 0x00006de0 <+20>: ldr.w r2, [r3, #4072] ; 0xfe8
0x00006de4 <+24>: mov.w r1, #0
0x00006de8 <+28>: ldr r2, [r7, #44] ; 0x2c
0x00006dea <+30>: orr.w r2, r1, r2
0x00006dee <+34>: str.w r2, [r3, #4072] ; 0xfe8
Even though the IntClear register is only being written to in the C code, GCC generates a read but then discards the resulting r2 value anyway. This register is write-only so that is what led to the bus fault. It also does some extraneous ORing and such. I was able to work around this issue by convincing GCC that the uint32_t type is an "unsigned int" and not a "unsigned long" which are both 32-bit on this platform but it appears that GCC doesn't treat them as equal and that leads to the above issue.
Once the above issue was worked around, I hit the malloc/free issue described above.
I am sort of disheartened to see how poorly gdb was able to step through your code with all optimizations turned off. I need to spend some time looking into that issue. I get truncated callstacks and sometimes it treats C functions with symbols as though they didn't have symbols at all.
-Adam
I am having an issue with UDP Sockets that only occurs when there is a lot of network traffic. I am transferring packets @100Hz and it works fine doing this when there isn't much traffic on the network. When there a multiple broadcast packets floating around, as is the case when I am running X-Plane, my application will eventually hang.
I have used SimpleSocket, mbedNet and one other thinking maybe it was a library thing, but all of them behave exactly the same.
I have found the following things:
1) Before this happens I get false-positives where it uses the same pack multiple times. (When I use a RecvFrom type function).
2) A few times later, the mbed board will eventually hang in the RecvFrom type of call.
3) I ended up writing a pacer routine on the reads, but this is merely a bandage until I can get this running normally.
I have a an interrupt routine running at 10Khz, but I tried disabling it and I still got the same result.
I've kind of run out of ideas. Any thoughts/suggestions would be most appreciated.
Here is the main loop using SimpleSocket.
The loop prints a ! every second, if it gets a packet it prints a R if the packet is valid it returns a packet and prints a W
-Doug