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 UDPYes 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 unsucessfulThat 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 waitingSNDTIMEO
clock-ticks
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
No there is not a (standard) way to do that. The function that finally sends the packet is
- Is there a way that FreeRtos can block my call to FreeRtos_Send() until the bits are pushed out of the PHY
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.
Yes and no, +TCP does not queue up outgoing packets. There is one queue though: the message queue to the IP-task, called
- 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
xNetworkEventQueue
.
But once the IP-task receives message eStackTxEvent
, it will work on it untill it is passed to DMA for transfer.
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
- Will setting the Queue size to 1 effectively achieve what I am asking in my point #1
pvPortMalloc()
always succeed? Have you run the project with stack checking on?