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.

send udp packets using NDK , questions on the TaskSleep function in socket



I want to send data from the ddr3 to PC using ethernet  when given a GPIO interrupt, now I've finished transfer data using UDP, but to further improve the data rate, I have 

the following question.

My task is as follows:

void udp_test()
{
SOCKET send = INVALID_SOCKET; // Sender socket.
struct sockaddr_in sout1; // Sender socket address structure
int i=0,count=0;
char* senddata;
int sentCnt;
senddata=(char *)DDR3BASEADDRESS;
// Allocate the file environment for this task
fdOpenSession( TaskSelf() );

// Create the send socket
send = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if( send == INVALID_SOCKET )
goto leave;

// Send socket: set Port = 5000, IP destination address = ANY
bzero( &sout1, sizeof(struct sockaddr_in) );
sout1.sin_family = AF_INET;
sout1.sin_len = sizeof( sout1 );
sout1.sin_port = htons(5000);

// Bind send socket
if ( bind( send, (PSA) &sout1, sizeof(sout1) ) < 0 )
{
printf("Send: %d",fdError());
goto leave;
}

//strcpy( sendBuffer, "Are you there?" );
for(i=0; i<1500; i++)
{
sendBuffer[i]=(char)i%(0xFF);
}
sout1.sin_addr.s_addr = inet_addr(UnicastAddr); // PC address is the destination
sout1.sin_port = htons(7); // Echo port (7) is where we want to send data
for(;;)
{
if(Ethernetswtich)
{
while(count++<1600)
{
do
{
//cycleDelay(5000);
TaskSleep(1);// this is a must,it means n ms send a packet ,it control the data rate
//0x040D2F65-0x03FFDCFA
sentCnt = sendto( send, senddata, 1024, 0, (PSA)&sout1, sizeof(sout1) );
}
while (sentCnt < 0);
senddata+=1024;// need to be direct back while finished
//printf (" Message sent to ethernet \n");
}
Ethernetswtich=0;
}
}

leave:
// We only get here on a fatal error - close the sockets
if( send != INVALID_SOCKET )
fdClose( send );

printf("Fatal Error\n");

// This task is killed by the system - here, we block
TaskBlock( TaskSelf() );
}

 as I see the function TaskSleep(1); is essential in the packet sending.  for  TaskSleep(1), the data rate can be 1MB/s. but I can't make it higher.

without the TaskSleep function or replace it with the cycleDelay(5000) function,  i  can't recieve any packet in wireshark on PC.

the cycleDelay() is as follows:

void cycleDelay (uint32_t count)

{

  uint32_t sat;

 

  if (count <= 0)

    return;

 

  sat = TSCL + count;

  while (TSCL < sat);

}


Why would i have to suspend the Task to send UDP packet?  is the speed has some limitation, so i can only reach 1MB/s?

do any one have some suggustions?

Thanks!!!

  • I'm attaching a file which is based off your code but uses fdSelect instead.  This allows sending of the packet as soon as the socket is available.  Could you try this and let me know if you see improvement?

    -John Demery

    /*
     * test.c
     *
     *  Created on: Jun 24, 2013
     *      Author: dilbert
     */
    
    #include <ti/ndk/inc/netmain.h>
    
    
    void udp_test()
    {
    	SOCKET send = INVALID_SOCKET; // Sender socket.
    	struct sockaddr_in sout1; // Sender socket address structure
    	int i=0,count=0, tmp;
    	char* senddata;
    	int sentCnt;
    
        // added these vars
    	struct   	timeval 	to;
        fd_set ibits, obits, xbits;
    
    	senddata=(char *)DDR3BASEADDRESS;
    
    	// Allocate the file environment for this task
    	fdOpenSession( TaskSelf() );
    
    	// Create the send socket
    	send = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    	if( send == INVALID_SOCKET )
    		goto leave;
    
    	// Send socket: set Port = 5000, IP destination address = ANY
    	bzero( &sout1, sizeof(struct sockaddr_in) );
    	sout1.sin_family = AF_INET;
    	sout1.sin_len = sizeof( sout1 );
    	sout1.sin_port = htons(5000);
    
    	// Configure our socket timeout to be 15 seconds
    	to.tv_sec  = 3;
    	to.tv_usec = 0;
    
    	setsockopt( send, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof( to ) );
    
    	// Bind send socket
    	if ( bind( send, (PSA) &sout1, sizeof(sout1) ) < 0 )
    	{
    		printf("Send: %d",fdError());
    		goto leave;
    	}
    
    	//strcpy( sendBuffer, "Are you there?" );
    	for(i=0; i<1500; i++)
    	{
    		sendBuffer[i]=(char)i%(0xFF);
    	}
    
    	sout1.sin_addr.s_addr = inet_addr(UnicastAddr); // PC address is the destination
    	sout1.sin_port = htons(7); // Echo port (7) is where we want to send data
    
    	for(;;)
    	{
    		if(Ethernetswtich)
    		{
    			while(count++<1600)
    			{
    				do
    				{
    					// Clear the select flags
    					FD_ZERO(&ibits);
    					FD_ZERO(&obits);
    					FD_ZERO(&xbits);
    
    					// We examine the UDP socket (since we got called by data coming in, this is rather pointless, but rather an exercise in using these functions)
    					FD_SET(send, &obits);
    
    					tmp = fdSelect( 4, &ibits, &obits, &xbits, &to );
    
    					if( tmp < 0 )
    						goto leave;
    
    					if( FD_ISSET(send, &obits) )
    					{
    						//0x040D2F65-0x03FFDCFA
    						sentCnt = sendto( send, senddata, 1024, 0, (PSA)&sout1, sizeof(sout1) );
    					}
    				}
    				while (sentCnt < 0);
    				senddata+=1024;// need to be direct back while finished
    				//printf (" Message sent to ethernet \n");
    			}
    			Ethernetswtich=0;
    		}
    	}
    
    	leave:
    	// We only get here on a fatal error - close the sockets
    	if( send != INVALID_SOCKET )
    	fdClose( send );
    
    	printf("Fatal Error\n");
    
    	// This task is killed by the system - here, we block
    	TaskBlock( TaskSelf() );
    }
    
    

  • dear Demery

    It seems not working, I change the function and can't recieve the packet on PC using wireshark. but i can debug and see the sentCnt=1024 which means  the socket has sent the packet?

    // Clear the select flags
    FD_ZERO(&ibits);
    FD_ZERO(&obits);
    FD_ZERO(&xbits);

    // We examine the UDP socket (since we got called by data coming in, this is rather pointless, but rather an exercise in using these functions)
    FD_SET(send, &obits);

    tmp = fdSelect( 4, &ibits, &obits, &xbits, &to );

    sorry to ask, but because i'm not that familiar with socket, what does this mean ?

  • Please note that there is a potential problem with the NIMU driver dropping packets when sending UDP packets in a loop:
    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/273906.aspx

    I think the fdSelect() solution only works with connected sockets.

    Ralf

  • Thank you for your reply, but the URL is my post^^^^^^^^^^