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.

C6678 UDP Receive task

Hello all,

I have a UDP TX socket and a UDP RX socket. I am using a semaphore to trigger a UDP TX since I have control over when to transmit a packet in my code. My question is how to do the same for the UDP receive task instead of block the task using TaskSleep(1);


My code for the 2 sockets is as follows:

 

void udp_rx_task_Fxn()
{
 SOCKET   sUDP = INVALID_SOCKET;     // Listen socket.
 struct   sockaddr_in sin1;         // Listen socket address structure
 int recvCnt;
 int tmp, k;

 // Allocate the file environment for this task
 fdOpenSession( TaskSelf() );

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

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


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

 sin1.sin_addr.s_addr = inet_addr(UnicastAddr); // PC address is the destination
 sin1.sin_port = htons(8); // port (8) is where we want to send data
 tmp = sizeof(sin1);

 for(;;)
 {
  //DM to DSP

  //Check for new incoming packets from Host
  recvCnt = recvfrom(sUDP, &ReceptMessage, sizeof(ReceptMessage), MSG_DONTWAIT, (PSA)&sin1, &tmp);
  if(recvCnt > 0)
  {
   switch (ReceptMessage.MsgId)
   {
   case DM_HEARTBEAT_MSG:
   ...
   }

  }
  TaskSleep(1); //??????????????????? how to use a different method to block a task
 }

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

 printf("Fatal Error\n");

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

void udp_tx_task_Fxn()
{
 SOCKET   sUDP = INVALID_SOCKET;     // send socket.
 struct   sockaddr_in sout1;         // send socket address structure
 int sentCnt;
 int i;

 // Allocate the file environment for this task
 fdOpenSession( TaskSelf() );

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

 // sUDP socket: set Port = 5001, IP destination address = ANY
 bzero( &sout1, sizeof(struct sockaddr_in) );
 sout1.sin_family = AF_INET;
 sout1.sin_len    = sizeof( sout1 );
 sout1.sin_addr.s_addr = inet_addr(UnicastAddr); // PC address is the destination
 sout1.sin_port = htons(8); // port (8) is where we want to send data

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

 for(;;)
 {
  ClearDspToDmMsg(&SendDsp2DMMessage);

  //wait for semDsp2Dm semaphore to be posted
  Semaphore_pend(semDsp2DM, BIOS_WAIT_FOREVER);

  if(SDsp2DMReadyMessagesbits.DSP_HEARTBEAT_MSGbit)
  {
  ...
  }


 }

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

 printf("Fatal Error\n");

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

}

 

  • Murad,

    The task object provides a method of manipulating task threads using a generic task handle. Task threads are executed on a priority based method. There is no other another equivalent API for similar API TaskSleep. Otherwise, you may think about SemPend API,If the semaphore count is zero, the task is placed on a waiting list for the semaphore and blocked.

    The Task Object access functions are as follows:
    TaskCreate() - Create new task thread
    TaskDestroy() - Destroy a task thread
    TaskSelf() - Get handle to current task thread
    TaskExit() - Exit (terminate) current task thread
    TaskYield() - Yield to another task thread at the same priority
    TaskSleep() - Block a task thread for a period of time
    TaskBlock() - Block a task thread
    TaskSetPri() - Set task thread priority level
    TaskGetPri() - Get task thread priority level
    TaskSetEnv() - Assign one of three private environment handles to task thread
    TaskGetEnv() - Retrieve one of three private environment handles.

  • Pubesh,
    I understand all the above functions!. My question is how to use a semaphore in the UDP receive similar to the one I am using in the UDP transmit?...if I use a semaphore with the UDP receive, where do I post "Semaphore_post()" in my code?...how would I know of an incoming packet?...to transmit, this is under the control of my code, but how to manage a receive event???...Please look at my code above

    Regards,

    Murad
  • Murad,

    If you are planning to use sem pend before receive, it requires someone post the semphore release, in the real time packet receive will be lose.
    Try to use, fdStatus(sUDP, FDSTATUS_RECV, &BytesToRead );
    Here, If the receive data available on this socket then you can receive the packet.
    In your case, sending and receiving the packet are different, You will lose the data definitely while blocking on receive side.

  • Thanks Pubesh,
    Where do I call the fdStatus?. I really don't care about what method to use as long as I don't miss received UDP packets and Don't waste time of other tasks. So, what would you do to enhance my code above?
  • Murad,
    What is the updated status? Did you try with fdStatus in the task? Are you excepting the example code for how to use this API.
  • Hello Pubesh,
    I still not sure how to use fdStatus(sUDP, FDSTATUS_RECV, &BytesToRead );. I still have to have infinity loop for(;;) so I don't exit the task, but how to use the fdStatus to let the scheduler service the other tasks without TaskSleep() or like I am doing with the TX task Semaphore_pend(semDsp2DM, BIOS_WAIT_FOREVER); that blocks the current task if semaphore count is zero?
    Do I need to check for BytesToRead inside the for(;;) loop and post a semaphore if BytesToRead > 0, otherwise the Semaphore_pend will block the current task...then we will come back to this task when the scheduler decide to?

    Regards,

    Murad
  • Murad,

    Apologize for the late reponse. Unforutely I have missed this thread due to holiday. I hope, you have find the solution for the UDP receive. Please find the some piece of code, if you still having issue. You can use this code on your UDP receive task,

    fd_set readfds, writefds, xfds; //Declare this inside TASK(udp_rx_task_Fxn())
    
    while(1)
    {	
           //Check for new incoming packets from Host
    
    	FD_ZERO(&readfds);
    	FD_ZERO(&writefds);
    	FD_ZERO(&xfds);
    
    	FD_SET(sUDP, &readfds);
    
    	fdvalue=fdSelect( 4, &readfds, &writefds, &xfds, &timeout ) ;
    	if(fdvalue< 0)
    		 LOG_printf(&trace,"No incoming data\n %d",fdvalue); 
    
    	if ( FD_ISSET( sUDP, &readfds ) )
    	{
    		recvCnt = recvfrom(sUDP, &ReceptMessage, sizeof(ReceptMessage), MSG_DONTWAIT, (PSA)&sin1, &tmp);
    		if ( recvCnt > 0 )
    	       		printf("Received PKTs %d\n", recvCnt);
    		else
    		{
    			retvalue = fdError();
    			printf("ERROR IN RCV %d\n", retvalue);
    		}
    	}
    	
    
    } // while 1

     

  • Thank you Pubesh and happy holidays!. I will try this code once I am done with other issues related to the MCSM/etc...

    Regards,

    Murad