FreeRTOS_accept does not return unless timed out (STM32F7)

goz3rr wrote on Tuesday, April 10, 2018:

Hello, this I’ve seen this problem a few times on posts from 2015, but all of them either don’t give an answer or seem to suggest that it was fixed in a later version. I figured I’d make a new topic since such a long time has passed.
(See: https://sourceforge.net/p/freertos/discussion/382005/thread/87b3b411/, https://sourceforge.net/p/freertos/discussion/382005/thread/5d30e1ae/ and https://sourceforge.net/p/freertos/discussion/382005/thread/31374882/)

I’m using FreeRTOS+TCP v10.0.1 on an STM32F769-Disco board, the onboard LAN8742A PHY with the included phyHandling.c and STM32F7xx NetworkInterface.c files.

My board is initializing fine and it responds to ICMP pings, however when I try to use the SimpleTCPEchoServer.c demo, it will reach the FreeRTOS_accept function (with FREERTOS_SO_RCVTIMEO set to portMAX_DELAY) and then get stuck at the end of it, on the xEventGroupWaitBits call. Enabling the debug printf and using wireshark shows that the TCP packets are being received and ACK’d, and the socket itself going through various states:

(.100 is my PC, .200 is the STM32)

FreeRTOS_IPInit
vTaskStartScheduler
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 1000
prvEthernetUpdateConfig: LS mask 00 Force 1
>> Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
vApplicationIPNetworkEventHook: event 0
network up
IP Address: 192.168.0.200
Subnet Mask: 255.255.255.0
Gateway Address: 192.168.0.1
DNS Server Address: 1.1.1.1
Socket 7 -> 0ip:0 State eCLOSED->eTCP_LISTEN
tcp echo server listening
Network buffers: 55 lowest 55
Network buffers: 54 lowest 54
Network buffers: 53 lowest 53
Gain: Socket 7 now has 1 / 20 child
prvSocketSetMSS: 1160 bytes for c0a80064ip:30562
Socket 7 -> c0a80064ip:30562 State eCLOSED->eSYN_FIRST
MSS change 1160 -> 1460
prvWinScaleFactor: uxRxWinSize 2 MSS 1160 Factor 0
Socket 7 -> c0a80064ip:30562 State eSYN_FIRST->eSYN_RECEIVED
TCP: passive 7 => c0a80064ip:30562 set ESTAB (scaling 1)
Socket 7 -> c0a80064ip:30562 State eSYN_RECEIVED->eESTABLISHED
Socket 7 -> c0a80064ip:30562 State eESTABLISHED->eLAST_ACK
Socket 7 -> c0a80064ip:30562 State eLAST_ACK->eCLOSE_WAIT

Changing the timeout to another value results in the FreeRTOS_accept function returning after the specified timeout, with a valid socket if there was a connecting during that time.

Say if I set the timeout to 60 seconds and try to send the echo. A few seconds later the echotool gives up saying the response timed out. about 60 seconds after starting (less if the FreeRTOS_accept had been waiting for a while already) FreeRTOS_accept will return a socket (that is not null) that will now happily let me read the data from it that was received, but when the echo sample tries to write it will now get stuck in a loop forever, since the FreeRTOS_send always returns it wrote 0 bytes (obviously).

Setting the timeout to a lower value like 100 milliseconds will result in the socket actually still being open by the time the FreeRTOS_accept call times out and allowing the proper sending and receiving over it, but now there’s a large (100ms at worst) delay before a socket can be opened.

Lowering the timeout to something very low will resolve the problem of long delays when opening a new socket, but wouldn’t I by wasting a lot of clock cycles then because of it constantly timing out, even when there is no new sockets?

What is causing FreeRTOS_accept to not work like it should (at least, as it should from what I could gather) and properly return once it has to without having to resort to what is essentially polling? Or am I completely misunderstanding this since it’s my first project with FreeRTOS?