sending DHCP via FreeRTOS_sendto() requires long delay

alager12345 wrote on Thursday, March 07, 2019:

When I single step through the DHCP code, it works (mostly). But if I turn off all break points and just let it run, then I do not get any traffic output on the wire, as can be seen by the debug terminal output:

prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
vDHCPProcess: timeout 10000 ticks
vDHCPProcess: discover
vAssertCalled( C:\projects\software\dpt2\Lib_FreeRTOS\list.c, 82

Now, if I put a break point OR a put 2 second delay in xNetworkInterfaceOutput() then I get the packet on the wire when I continue the run (in the break point case). This makes me think that some other task is getting starved, but since the only thing I’m attempting right now is DHCP (no custom tasks yet), I don’t know what it could be.
Also, the 2 second delay breaks ARP and ping (when I set a static IP), so that’s no good.
Here is the debug terminal output with a delay added.

prvIPTask started
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
vDHCPProcess: offer a03004cip
vAssertCalled( C:\projects\software\dpt2\Lib_FreeRTOS\list.c, 82

Any ideas?

heinbali01 wrote on Friday, March 08, 2019:

If it helps to put a delay within xNetworkInterfaceOutput(), could it be that the NetworkBuffer is released too early, i.e. while it is still being delivered?

Or are you running low on Network Buffers?

Have you logged these actions: send, get an interrupt on TX-complete, release?

You get an ASSRT in vListInsertEnd(): can you find out from where it is called?

alager12345 wrote on Friday, March 08, 2019:

I can also put the delay into prvSendDHCPDiscover() before the call to FreeRTOS_sendto() and it also causes things to start working.
I did consider the free happening too soon. So I changed the interrupt from TX_DONE to TX_FINISH. This didn’t change the behavior. I also inspected my buffer tracking array, and found that it’s only using the first element, so it looks to be one for one right now. One buffer allocated, one buffer freed.

With regards to the ASSERT, that is due to the other thread regarding the buffer alignment.
https://sourceforge.net/p/freertos/discussion/382005/thread/40793cc5ad/?limit=250#3e0e

alager12345 wrote on Friday, March 08, 2019:

Logging the sequence, with no delays added

prvIPTask started
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Sening buff 0x1000b208
Clearing buff 0x1000b208
vDHCPProcess: timeout 10000 ticks
vDHCPProcess: discover
vAssertCalled( C:\projects\software\dpt2\Lib_FreeRTOS\list.c, 82

Logging the sequence, with a delay added before FreeRTOS_sendto()

prvIPTask started
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Sening buff 0x1000b208
Clearing buff 0x1000b208
vDHCPProcess: offer a030057ip
vAssertCalled( C:\projects\software\dpt2\Lib_FreeRTOS\list.c, 82

The Clearing buff is inside the TX_FINISH ISR.

alager12345 wrote on Saturday, March 09, 2019:

Now that I’ve solved my buffer issues, this one sort of resolves itself. It looks like the first DHCP discover request is still not sent, but all subsequent ones are. So, for now, I am working, just with one delay. It’s still a nag, but I can see that my buffer descriptor is “allocated” and then freed, so there doesn’t appear to be a memory leak from it, just a startup delay.

heinbali01 wrote on Saturday, March 09, 2019:

It looks like the first DHCP discover request is still not sent

I’m curious about this.
When a UDP packet it sent to a particular address, the first UDP packet will be turned into an ARP request.
But as DHCP is sent to a broadcast address, it doesn’t need ARP resolution.
Can you see if the first request leads to calling xNetworkInterfaceOutput() with a DHCP/UDP packet?

There is a flag called dhcpBROADCAST, which will only be used in the second attempt. Maybe that declares the behaviour. Also look for xDHCPData.xUseBroadcast

alager12345 wrote on Monday, March 11, 2019:

So back to putting in a break point, the first DHCP discover packet is sent on the wire. It has the Unicast flag set. Once this goes out on the wire, then the whole machinery of DHCP works as expected.
Now, if I do not set a break point nor have a delay, then the first packet disapears somewhere (never appears on the wire), but the second discover does make it out and it has the Broadcast flag set.
There are no ARP requests before or during this process. Not until the end, when the DUT sends a Gratuitous ARP.