Communication Protocol: Ethernet UDP (high traffic)
Our application calls FreeRTOS_recvfrom() while there are messages waiting using the field xWaitingPacketsList.
At the end of the while loop we expect to handle the latest UDP packet that recevied in our channel.
Our application receives the latest package in our socket but not in the IPTask (channel) queue.
Investigation & Conclusions
We have Windows PC that sends UDP packets in high traffic to our target board.
Each packet has an ID Number that we can track them in our application
Our application receives the packets and handle them
At some point we stop the PC from sending data and we compare between the ID in our application to the latest ID packet that the PC sent
We are able to see that the PC holds a higher ID then our application
If we fake the filed WaitingMessages in the IPTask.NetworkQueue.WaitingMessages, the application handles the latest ID packet. Is it possible the the IPTask received multiple packets in one RxEvent and sends the first packet (the oldest) to our socket?
We want to be able to get the latest UDP packet that was sent to our application. The previous packets are irrelevant to us therefore it is acceptable to ignore them.
How can we achieve such behavior?
How can we configure IPTask queue to sent the latest packet to the socket?
As this is a very custom requirement I don’t think there is a way to do this in the FreeRTOS+TCP without modifying the stack itself.
If I understand your question correctly the following logic should work. Though this can be added in multiple places in the stack, I would try to do it in the sockets recvfrom implementation (FreeRTOS_recvfrom) if I want to easily preserve the usual behavior of the UDP sockets as well:
diff --git a/source/FreeRTOS_Sockets.c b/source/FreeRTOS_Sockets.c
index af1248a..8804c95 100644
@@ -958,6 +958,24 @@ int32_t FreeRTOS_recvfrom( const ConstSocket_t xSocket,
+ if( ( ( UBaseType_t ) xFlags & ( UBaseType_t ) FREERTOS_DISCARD_OLD ) != 0U )
+ while (lPacketCount > 1)
+ /* The owner of the list item is the network buffer. */
+ pxNetworkBuffer = ( ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) );
+ /* Remove the network buffer from the list of buffers waiting to
+ * be processed by the socket. */
+ ( void ) uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
+ /* Release the buffer */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
/* The owner of the list item is the network buffer. */
pxNetworkBuffer = ( ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList
Note: Non tested code.
FREERTOS_DISCARD_OLD is a custom flag to enable the behavior.
UDP packets are NOT guaranteed to be delivered in order and there are multiple factors that can impact delivery (such as network congestion). As a result, you cannot guarantee that the latest packet received by the stack was the latest packet sent by the other party. You should, therefore, re-think if you want your application to rely on this behavior.
Is it possible for you to determine whether the packet you get from FreeRTOS_recvfrom is stale, then discard if it is stale and call FreeRTOS_recvfrom again?
It is disabled with an #if 0 because we didn’t have the time to document it. But it works.
lCount = FreeRTOS_recvfrom( xSocket,
if( lCount <= 0 )
if( FreeRTOS_udp_rx_size() == 0 )
/* This was the latest in the queue. */
/* Loop to read the next packet. */
I do find it strange that packets get out-of-order, or that that get dropped along the way.
I have never seen that a UDP packet got dropped or swapped on a LAN. I would also recommend to run WireShark and make a long PCAP, using a “udp.port=xx” filter.
If you have implemented the logging macro FreeRTOS_printf(), you may want to call vPrintResourceStats() in every loop of the NetworkInterface EMAC task like here.
It will print warnings when the IP-stack runs out of resources.
Unfortunately UDP packets can get reordered (nowadays) with smarter network cards with multiple internal parallel packet processing queues. Since there is no guarantee about the order it’s done and it happens in reality especially with high traffic load.