This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem with real time UDP stream

I am using the launchpad to prototype a UDP based real time data monitoring system.

The launchpad is being fed with 16 bytes through the SSI0 interface every 100 microseconds. SSI is running at speed of 7.5MHz clock.

SSI0 generates an interrupt upon receiving the data and it sets a status flag =1.

Once ISR is finished, the main while loop has a if statement that checks if status ==1 and then proceeds to send the udp packet consisting of data received on the SSI0 interface.

void udp_initialize(void){
	udp_pcb = udp_new();
	IP4_ADDR(&server_ip, 192, 168, 1, 27);
	IP4_ADDR(&local_ip, 192, 168, 1, 32);
	udp_bind(udp_pcb, &local_ip, 2222);
	p = pbuf_alloc(PBUF_TRANSPORT, sizeof(g_ulDataRx0), PBUF_RAM);
	udp_connect(udp_pcb, &server_ip, 2222);
	udp_recv(udp_pcb, recvCallback, NULL);
}

Above code is used to initialize the udp pcb and other required stuff.

if(status==1){

    memcpy(p->payload, g_ulDataRx0, sizeof(g_ulDataRx0));
    udp_send(udp_pcb, p);
    pbuf_free(p);
   //send();
    status=0;

}
WatchdogReloadSet(WATCHDOG0_BASE, watchdogInterval);

Above code is running inside the main while loop.

The following code is for the SSI0IntHandler.

void SSI0IntHandler(void)
{
	SSIIntClear(SSI0_BASE, SSI_RXFF);
	int i=0;
	volatile uint32_t bytes[4];
	for (i=0; i<NUM_SSI_DATA; i++){
		SSIDataGet(SSI0_BASE, &g_ulDataRx0[i]);
		bytes[0] = (g_ulDataRx0[i] & 0x000000FF) << 24u;
		bytes[1] = (g_ulDataRx0[i] & 0x0000FF00) << 8u;
		bytes[2] = (g_ulDataRx0[i] & 0x00FF0000) >> 8u;
		bytes[3] = (g_ulDataRx0[i] & 0xFF000000) >> 24;
		g_ulDataRx0[i] = bytes[0] | bytes[1] | bytes[2] | bytes[3];
	}
	status=1;
	//send();
//For loop to send out data on the UART for debug.
//	for (i=0; i<NUM_SSI_DATA; i++){
//		UARTprintf("%x\n", g_ulDataRx0[i]);
//	}
	SSIIntEnable(SSI0_BASE, SSI_RXFF);

}

The problem I am facing is, once the microcontroller resets, the UDP stream is perfectly running at ~8Mbps but suddenly after sometime there is a drop in throughput. At some point it completely stops the transmission but after 4 - 5 seconds it again starts pumping at ~3-4Mbps.

The following screenshot should make the problem more clearly visible.

So, I am trying to figure out what is causing this. I expect it to transmit data in real time using whatever bandwidth it requires.

If it is necessary, I will post some more of the relevant code.

  • Hello Salil

    1. Is the Ethernet sending all the data packets as expected?
    2. Is it possible to check which part of the ethernet throughput belong to a UDP stream creation and which parts is actually data transmission?

    Regards
    Amit
  • Thank you for your response.

    1. Yes the data packets are arriving on the PC as expected. I inserted a "count" value inside the payload and saw it arriving on the PC. When the data rate drops, the packets keep coming in for some time even after the SSI0 data stream from external device is halted.

    2. I dont get what you are trying to say. Is it that you want logs from packet sniffing tool like Wireshark? Or are you referring to my code?

  • Hello Salil

    1. Check the LWIP timer interrupt which schedules the transaction to manage the data rate

    2. I am referring to your code.

    Regards
    Amit
  • Since, this is my first time playing with lwip I have no clue how the lwip timers operate and where exactly I should be looking. So could you guide me on this one?

  • Hello Salil

    Search for timer in lwiplib.c file. There is a define which defines the periodicity of the Timer used for LwIP.

    Regards
    Amit
  • Hi Amit,

    This is what I found inside lwiplib.c

    #define HOST_TMR_INTERVAL       0

    Also, this is the code where actual data transfer happens:

    void main(){
    ....
    other stuff happening here
    ....
    
      while(1){
        if(status==1){
            p = pbuf_alloc(PBUF_TRANSPORT, sizeof(g_ulDataRx0), PBUF_RAM);
        	memcpy(p->payload, g_ulDataRx0, sizeof(g_ulDataRx0));
        	udp_send(udp_pcb, p);
        	pbuf_free(p);
        	//send();
        	status=0;
    
        }
        WatchdogReloadSet(WATCHDOG0_BASE, watchdogInterval);
      }
    }

  • Hello Salil,

    My apologies,. The timer is defined in lwipopts.h

    #define HOST_TMR_INTERVAL 100 // default is 0

    Regards
    Amit
  • the lwipopts.h had the HOST_TMR_INTERVAL set to 100.

    I even tried playing around with timer values but no luck.

    I am attaching the project just in case you want to have a look. I have modified the enet_io example.6761.enet_io.rar

    It may have some files that are being excluded from the build. (httpd.c, httpd.h, httpd.structs.h, functions.h)

  • Hello Salil,

    Since I do not have a similar setup it may take time to do something similar.

    Regards
    Amit
  • As lame as it may sound, I found the problem to be with the SSIDataGet. In debug mode, I found out whenever there was sudden drop in throughput, controller was halting completely at SSIDataGet function. So, I replaced it with SSIDataGetNonBlocking and everything is working fine. I will monitor the performance thoroughly to see if there are any further problems and contact you if I find any.
    Thanks for your support :)

  • Hello Salil

    What do you mean by halting at SSIDataGet. Using the non blocking function would mean that the if the SSI does not have data then it shall return nothing but status indicating no data available.

    Regards
    Amit
  • I would let the program run normally and monitor the ethernet throughput on task manager. Whenever I saw the data rate dip to 0Mbps I would pause the program and see the status in debug window. There I saw the program being stuck at SSIDataGet.

    The interrupt is generated on RXFF which according to my understanding is generated only after data has been placed in FIFO. So I do not understand why the program stops at SSIDataGet.

  • Hello Salil,

    The SSIRXFF means that the RXFIFO is full. In such a case the CPU must read only the number of bytes that the FIFO can hold. E.g. it should read out 8 bytes only. If the loop on the other hands try to read more than 8 on RXFF interrupt it must wait for the FIFO to have some data.

    Regards
    Amit