UDP Speed too slow

Hello Everyone,

I am working on a project where my uController will serve a UDP request to send data at around 100kbits per second which is very slow speed.

I have implemented the FreeRTOS+TCP stack using a reference design in TI ARM Cortex M4 i.e. TM4C129EXL uController running at 120MHz.

Functionality wise the firmware is working fine. However the speed is very slow. If I try to pull data of 48bits at more than 10Hz, the controller will miss some of the requests.

The 48bits data is 16bits adc value of three sensors. The time it takes to read all three sensors is negligible i.e. less than 5usec.

I have the following settings;

#define configTICK_RATE_HZ 1000
#define ipconfigIP_TASK_PRIORITY 4
#define ipconfigNIC_TASK_PRIORITY 4
#define UDP_Com_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )

I am not very familiar with FreeRTOS and seeking your help.
I thank you in advance for your cooperation.

Regards,
Iftikhar

To be clear: the host sends 1 (UDP) request to the MCU and gets 1 response with the 48 bit ADC values, right ? That shouldn’t be a problem.

  • How do you know that packets are dropped ?
  • Is the MCU missing requests or misses the host responses ?
  • Did you have a look with Wireshark at the communication ?
  • Did you add e.g. a sequence counter to the request packet for testing/verification ?

I‘d start checking the host request path. How much requests/second can be received w/o drops e.g. using a sequence counter checked by the MCU and without sending responses.
Then I’d do the same with the MCU response path to get an estimation about the basic networking performance.
Alternatively you can use the iperf tool, of course.

Do you fetch the ADC values and send back the response in the same task where you received the response or is any further task/queue involved ?
You should check every stage of the data flow to find the reason for unexpected delay.
Using Wireshark at the 1st place also helps to quickly see the response time thanks to the packet timestamping.

What else is running on the MCU ? Any higher prio task or interrupt which could starve one of the stages of the request/response flow ?

Good luck !

A minor remark:

Alternatively you can use the iperf tool, of course.

The server implementation of iperf that I have is only tested with TCP, not with UDP.

Hi @hs2,

Thank you for your reply.
Here are the answers for your questions;

  1. I am using YAT to send packets and receive them. If i keep the interval of sending requests at every 500msec, I can see YAT-Terminal prints with each request sent out there is a reply from controller. I have also written my own version of C program to send data at faster rate and I have seen the same behavior. My C program only sends second request if it receives reply from the controller. I simulated controller with another C application i wrote and runs on my laptop. This simulates the controller and my simulator will always reply even at faster rate.

  2. I am pretty much sure it is not dropping the packets and the controller is missing to reply to the requests. The reason is my controller is directly connected to my laptop.

  3. I did not check with Wireshark because as I said above in 1. that I simulate the controller by a C application and I can read and very high speed without missing any single packet. Also as mentioned above in 2. my controller is directly connected to my laptop.

  4. I may add the sequence counter but I am pretty much sure my controller is slow in replying.

  5. I fetch ADC values and send back the response in the same UDP task. I have the UDP task the highest priority.

  6. I have total 4 task running on the controller UDP has the highest priority.

  7. There is no interrupt running.

Fingers crossed, any idea ?

Hi,

I have removed everything and now in my UDP task, I am just receiving a packet and sending a fixed constant. I am no more reading any ADC anything.
Here is my code;

void UDPCommunicationTask( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority )


{
xTaskCreate( prvUDPCommandInterpreterTask, “UDP COMM”, usStackSize, ( void * ) ulPort, uxPriority, NULL );
}
/ *-----------------------------------------------------------* /

void prvUDPCommandInterpreterTask( void *pvParameters )
{
int32_t lBytes, lByte;
char cRxedChar, cInputIndex = 0;
char datasize;
static char cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];
static char cLastInputString[ cmdMAX_INPUT_SIZE ], cInputString[ cmdMAX_INPUT_SIZE ];
BaseType_t xMoreDataToFollow;
struct freertos_sockaddr xClient;


memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );

/* Attempt to open the socket.  The port number is passed in the task
parameter.  The strange casting is to remove compiler warnings on 32-bit
machines. */
xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL );
uint32_t i;
if( xSocket != FREERTOS_INVALID_SOCKET )
{
	for( ;; )
	{
		/* Wait for incoming data on the opened socket. */
		lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength );
		if (lBytes > 0)
		{	    
	          cOutputString[0] = 0xA5;
	          FreeRTOS_sendto( xSocket, cOutputString,  strlen( ( const char * ) cOutputString ), 0, &xClient, xClientAddressLength );
	            
		}
       }

}

}

Here is the snapshot of the missed packet from controller;temp1

Any idea, where should I modify to increase the speed ?

Seems that the problem can’t be caused by the echo task code…
So it’s either an issue with the network stack configuration and maybe related (heap) allocation of network buffers or the ethernet/MAC driver :wink:
I’d really add a sequence counter checked by MCU if it’s incremented by 1 for each received request. Then you know if there is a problem receiving packets or not.
Packets can be dropped by the MAC driver and the stack, too. Also flaky cables and/or plugs might cause interesting effects.
I’d also propose to check if you’re running out of network buffers. The stack might wait for network buffers getting freed if running out of free buffers.
I’d for sure use Wireshark to see what’s going on.
Sorry - there is no obvious solution of the problem :thinking:

1 Like

@hs2

Hi Hartmut,

Thank you for highlighting the potential sources that may be contributing.
I will be sparing some time to increase the heap. The network buffers could be the problem because of the fact I saw yesterday that it seems the controller some time do not reply even when I send request at very slow speed of 0.5sec interval.

I will be updating you as soon as I implement and test it sometime today.

Thank you for your time
Regards,
Iftikhar

Hello,

I am sorry for my very late reply.
I thank you all specially hs2 for your time and help. Well I figured out there wasnt any problem with the FreeRTOS and its UDP stack.
The problem was with my setup as I was using a virtual machine under my laptop for sending the data packets plus my Laptop was connected via Wifi to my home router though my device was directly connected to the router. I found my home wifi network is very busy too.

I changed my setup to my office PC and connected my device to my office LAN and everything started working just fine.

Here are the snapshot of my an LED toggle. Notice when a UDP packet is received the LED goes High as indicated by the rise of the pulse and the device serves the udp request. At the end of the service the device send a reply to the remote client and turns of the LED as indicated by fall of the pulse.

I thank you all for your help and time.
Regards,
Iftikhar

Were you running FreeRTOS on the virtual machine? Or was FreeRTOS the receiver? If FreeRTOS was on the virtual machine I would be very interested on which virtual machine and how you the virtual machine gave access to the network.

Hi Richard,

I was running the FreeRTOS on my micro-controller while i was accessing it through my virutal linux machine.

I think that when you use WiFi, you will always see longer delays, even when you are the single WiFi user.
Wired Ethernet is just more efficient than a radio connection.

Here is a good text about WiFi performance, in which the author found latencies of almost 60 ms.
Doing a ping on a LAN typically lasts 1 ms or less.

1 Like