FreeRTOS_sendto – Is this a blocking call

Is there a way to make the call to FreeRTOSsendto blocking? When it returns I want to make sure that the data has been sent I am using UDP

FreeRTOS_sendto – Is this a blocking call

Is there a way to make the call to FreeRTOSsendto blocking? When I returns I want to make sure that the data has been sent I am using UDP
Yes sure that is possible. Please have a look here See also the macro’s ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME and ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME here For many socket options, it is important to apply them to a socket just after its creation, but FREERTOS_SO_SNDTIMEO and FREERTOS_SO_RCVTIMEO may be changed any time. The send() functions have a flag, in which you can pass FREERTOS_MSG_DONTWAIT, meaning to ignore the time-outs set on this socket.

FreeRTOS_sendto – Is this a blocking call

Yes I read the documentation but it was not clear to me. If FREERTOSSOSNDTIMEO is speficied to a non zero value – that means the call to FREERTOSSOSNDTIMEO will block attempting to send the packet via UDP and when it returns – if return is non zero – UDP sent sucessful if return is zero – UDP unsucessful Is that right ?

FreeRTOS_sendto – Is this a blocking call

will block attempting to send the packet via UDP and when it returns if return is non zero – UDP sent sucessful if return is zero – UDP unsucessful
That is true: the length of the packet is returned in case of success, and zero is returned when either of these went wrong:
  • There was no network buffer available, even after waiting SNDTIMEO clock-ticks
  • The message buffer to the IP-task (xNetworkEventQueue) didn’t have space to accept a new message, also after waiting SNDTIMEO clock-ticks
So it is useful to call sendto() in a blocking way, although when an application is well tuned, the function will never block. As you understand: a non-zero return code from sendto() only guarantees that a messages has been passed to the IP-task. When there is a Link Status with a switch or a router, I don’t see any reason why the UDP packet won’t be sent out through the PHY. What happens after that is unknown: there are no guarantees that an Ethernet packet will arrive at the destination. To be sure, you will need some ACK-ing mechanism. Although in practice, on a good quality LAN, the success rate for packet deliver is 100%. But don’t rely on it. Hein

FreeRTOS_sendto – Is this a blocking call

Thanks you for your clarification Hein. When sucesive UDP packets are pushed to FreeRtos – is the order of delivery guaranteed (i.e. they appear in the same order) I am experiencing a strange behaviour (and it may not be FreeRtos) where some UDP packets from before (that were already delivered before) are being “played back” As an example – I do a call to FreeRtos_Send and deliver packets 1, 2, 3, 4, 5 And every once in a while I see 1, 2, 3, 1, 2

FreeRTOS_sendto – Is this a blocking call

UDP packets are just sent onto the network and routed however the infrastructure between sender and receiver happens to route them. There are no guarantees in the order in which they will be received, or even if they will be received at all. If you need such guarantees then you either need to use TCP, or build these controls into the protocol that the UDP packets are carrying. https://www.freertos.org/FreeRTOS-Plus/FreeRTOSPlusTCP/UDP.html

FreeRTOS_sendto – Is this a blocking call

I had prepared the text here below before reading Richard’s remarks. he was quicker than I am. Here is my text, which is very similar to Richard’s view: Formally, it is not guaranteed that Ethernet packets arrive in the same order as they have been sent. But in practice, especially on a LAN, packets will arrive in the same order. The PHY will reattempt to deliver a packet in case it detects a collision. The TCP protocol can handle all these exceptions perfectly well. UDP, on the contrary will deliver the raw packets. And at most, a packet may be dropped. The order “1, 2, 3, 1, 2” sounds very strange to me. It means that packet 1 and 2 are transmitted 2 times. Why would that be and who does the retransmissions? I wouldn’t know. The FreeRTO+TCP library will only transmit each UDP packet once, that is for sure. Even when the PHY sees (false) collisions, the order of arrival would have been “1, 1, 2, 2, 3”, and not “1, 2, 3, 1, 2” I suppose that your application is not repeating messages? I’m puzzled about your observations. Have you looked with WireShark already?

FreeRTOS_sendto – Is this a blocking call

Hein & Richard – Yes I have verified that the application is not repeating messages and this seems to be a peculiar problem. 1. Is there a way that FreeRtos can block my call to FreeRtos_Send() until the bits are pushed out of the PHY 2. I am assuming that FreeRtos has a Queue that queues up the UDP packets pushed by the App. Can this Queue be reduced to size 1 3. Will setting the Queue size to 1 effectively achieve what I am asking in my point #1 Regards

FreeRTOS_sendto – Is this a blocking call

  1. Is there a way that FreeRtos can block my call to FreeRtos_Send() until the bits are pushed out of the PHY
No there is not a (standard) way to do that. The function that finally sends the packet is xNetworkInterfaceOutput(). As a test you could add some code there. When the function leaves, the packet may still be “in transfer”. But this should last less than a ms.
  1. I am assuming that FreeRtos has a Queue that queues up the UDP packets pushed by the App. Can this Queue be reduced to size 1
Yes and no, +TCP does not queue up outgoing packets. There is one queue though: the message queue to the IP-task, called xNetworkEventQueue. But once the IP-task receives message eStackTxEvent, it will work on it untill it is passed to DMA for transfer.
  1. Will setting the Queue size to 1 effectively achieve what I am asking in my point #1
I’m afraid that you’ll have to make some code your self. I must say that I have never heard of +TCP sending out UDP packets twice. May you want to show the code that sends the UDP packets? Can you attach a PCAP file that shows the double UDP packets? Are you constantly creating new sockets ( as I understood from you first post ), or do you re-use the socket over and again? Have you checked standard things like the heap and the stacks? Does pvPortMalloc() always succeed? Have you run the project with stack checking on?