udp socket datagram block ethernet

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

udp socket datagram block ethernet

Jump to solution
846 Views
emanueletrapani
Contributor III

hi, i'm working on frdmk64f demoboard, mqx 4.1 and CW 10.6

i have multiple task in my application. one of which receive from udp socket, and other manage the comunication of other stream socket. normally every task works fine: i send from my pc the datagram and the application elaborate it, while i have other stream comunication opened that works fine.

but sometimes, when i send a datagram, it is not received and cause a temporary block of ethernet device, of every open socket. after a variable time from the datagram is not received, always <10 second, every socket resumes to work and elaborate every packets, sent from my pc in this variable time.

so i have not lost any data, just the datagram is not received.

the udp task is still wait in the blocking recvfrom. the other task wait, during this time, in the RTCS_selectset() function untill something happens and they resume work.

i would to know why the not elaborated udp packet cause this block state for a variable time, always < 10 second.

0 Kudos
1 Solution
468 Views
RadekS
NXP Employee
NXP Employee

Hi Emanuele,

It is hard to say what could be reason for that behavior. We do not know about any specific issue that causes behavior according your description. Unfortunately it is hard to predict what could be wrong.

Could you please share more information (like example project (code snippet), log from wireshark, your modifications in RTCS macros, …)?

Important may be using of receive-nowait (OPT_RECEIVE_NOWAIT) and receive-push (OPT_RECEIVE_PUSH) socket options,…

Problem could be also in software structure where flow control cannot handle with situation when we lost some datagram. Next possible issue could be in task priorities,…

You could also try change RTCSCFG_UDP_MAX_QUEUE_SIZE definition.

Default value is 1. You could change it for example to 10. In this case you can call UDP recv() without blocking (UDP datagrams are buffered). For example:

#define RTCSCFG_UDP_MAX_QUEUE_SIZE 10

BTW: In MQX 4.2 we could set Receive-Buffer Size also for UDP by socket options. In that case we don't need modify RTCSCFG_UDP_MAX_QUEUE_SIZE definition.

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
3 Replies
469 Views
RadekS
NXP Employee
NXP Employee

Hi Emanuele,

It is hard to say what could be reason for that behavior. We do not know about any specific issue that causes behavior according your description. Unfortunately it is hard to predict what could be wrong.

Could you please share more information (like example project (code snippet), log from wireshark, your modifications in RTCS macros, …)?

Important may be using of receive-nowait (OPT_RECEIVE_NOWAIT) and receive-push (OPT_RECEIVE_PUSH) socket options,…

Problem could be also in software structure where flow control cannot handle with situation when we lost some datagram. Next possible issue could be in task priorities,…

You could also try change RTCSCFG_UDP_MAX_QUEUE_SIZE definition.

Default value is 1. You could change it for example to 10. In this case you can call UDP recv() without blocking (UDP datagrams are buffered). For example:

#define RTCSCFG_UDP_MAX_QUEUE_SIZE 10

BTW: In MQX 4.2 we could set Receive-Buffer Size also for UDP by socket options. In that case we don't need modify RTCSCFG_UDP_MAX_QUEUE_SIZE definition.

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
468 Views
emanueletrapani
Contributor III

thank you RadekS.

i change the priority of RTCS to 5, before to create it, and it seems work properly.

_RTCSTASK_priority=5;

i tried to use also

#define RTCSCFG_UDP_MAX_QUEUE_SIZE 10

but it does not change anything

0 Kudos
468 Views
emanueletrapani
Contributor III

hi RadekS, thank you for the answer.

this is a semplified version of my app that have the same problem.

discovery task that handle udp connession: receive the msg i send from my pc and if all right print some string on serial output.

void DiscoveryTask(uint32_t param){

  uint32_t udpsock;

  sockaddr udpsockaddr;

  uint16_t addrlen;

  uint32_t err;

  unsigned char discovery_rx_datagram[50];

  uint16_t rx_len;

  sockaddr rx_addr;

  uint16_t rx_addr_len=sizeof(sockaddr);

  /* Prepare IPv4 socket*/

  udpsock=socket(PF_INET, SOCK_DGRAM, 0);

  if (udpsock == RTCS_SOCKET_ERROR){

  fputs("Error: Unable to create socket for IPv4 UDP connections.", stderr);

  _task_block();

  }

  memset((char *) &udpsockaddr, 0, sizeof(udpsockaddr));//aggiunta

  ((sockaddr_in*) &udpsockaddr)->sin_family = AF_INET;

  ((sockaddr_in*) &udpsockaddr)->sin_port = PORT;

  ((sockaddr_in*) &udpsockaddr)->sin_addr.s_addr = INADDR_ANY;

  addrlen=sizeof(udpsockaddr);

  //Try to bind to socket until successful

  while(1){

  err = bind(udpsock, &udpsockaddr, addrlen);

  if(err == RTCS_OK){

  break;

  }

  fprintf(stderr, "Error 0x%X: Unable to bind IPv4 socket.\n", err);

  _time_delay(10000);

  }

  //Accepts incoming datagrams

  while(1){

  err=recvfrom(udpsock,discovery_rx_datagram,50,0,&rx_addr,&rx_addr_len);

  if(err==RTCS_ERROR){

  //fprintf(stderr, "Error receiving UDP\n", err);

  fprintf(stderr, "\n\rDiscovery: error receiving udp packet");

  fprintf(stderr, "\n\rerror: %x",RTCS_geterror(udpsock));

  continue;

  }

  rx_len=(uint16_t)err;

  fprintf(stderr, "\n\rDiscovery: received udp packet");

  fprintf(debug_uart,"\n\rdiscovery packet is: ");

  for (uint8_t j=0;j<err;j++) {

  fprintf(debug_uart,"%x ",discovery_rx_datagram[j]);

  }

  //Datagram received - check format

  if(discovery_rx_datagram[0]==ID && discovery_rx_datagram[1]==LEN && rx_len==(discovery_rx_datagram[1]+3)){

  fprintf(stderr, "\n\rDiscovery: dgram valid");

  }

  else{

  fprintf(stderr, "\n\rDiscovery: DGRAM not valid");

  continue;

  }

  }

}

in the main task, after i initialize the ethernet device and i start discovery task

TCP2SERservsock=socket(PF_INET, SOCK_STREAM, 0);

  if (TCP2SERservsock == RTCS_SOCKET_ERROR){

  fputs("Error: Unable to create socket for IPv4 connections.", stderr);

  _task_block();

  }

  ((sockaddr_in*) &TCP2SERservaddress)->sin_family = AF_INET;

  ((sockaddr_in*) &TCP2SERservaddress)->sin_port = PORT2;

  ((sockaddr_in*) &TCP2SERservaddress)->sin_addr.s_addr = INADDR_ANY;

  err = bind(TCP2SERservsock, &TCP2SERservaddress, sizeof(TCP2SERservaddress));

  if(err != RTCS_OK){

  _task_block();

  }

  err = listen(TCP2SERservsock, 0);

  if (err == RTCS_OK){

  fprintf(stderr,"TCP2SERV listening on port2\n\r");

  }

  else{

  _task_block();

  }

  sockaddr_len=sizeof(TCP2SERVtempaddress);

  memset(&TCP2SERVtempaddress,0,sockaddr_len);

  TCP2SERsockets2=accept(TCP2SERservsock, &TCP2SERVtempaddress, &sockaddr_len);

  t=FALSE;

  setsockopt(TCP2SERsockets2,SOL_TCP,OPT_RECEIVE_NOWAIT,&t,1);

  while(1) {

  if (TCP2SERsockets2==0){

  TCP2SERsockets2=accept(TCP2SERservsock, &TCP2SERVtempaddress, &sockaddr_len);

  }

  rx_count=recv(TCP2SERsockets2, tcp_rx_buf, 24, 0);

  if(rx_count==RTCS_ERROR){

  fprintf(stderr,"TRANSP: Shutting down sock %d",i);

  err=shutdown(TCP2SERsockets2,FLAG_CLOSE_TX);

  if(err!=RTCS_OK){

  fprintf(debug_uart, "TRANSP: Shutdown %d err: 0x%X\n\r",i,err);

  }

  TCP2SERsockets2=0;

  }else if(rx_count!=0){

  fprintf(debug_uart, "\n\rReceived %d bytes :\n\r",rx_count);

  for (uint8_t j=0;j<rx_count;j++) {

  fprintf(debug_uart, "%x ",tcp_rx_buf[j]);

  }

  }

  }

this function print a string of bytes i sent from my pc in port2.

i sent several udp packets before to see this error, here i post when the error happens.

my pc program send the udp datagram and i send a lot of times the string of bytes (01 02 03 04) so i read in the serial output:

...

Received 4 bytes :

01 02 03 04

Received 4 bytes :

01 02 03 04

Received 4 bytes :

01 02 03 04

[--------------------------------(i write it, it is not a serial output)]

Received 24 bytes :

01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04

Received 24 bytes :

01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04

Received 24 bytes :

01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04

Received 24 bytes :

01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04 01 02 03 04

Received 8 bytes :

01 02 03 04 01 02 03 04

...

the last string of 4 bytes is the last string i read correctly when i send it. the other string of 24 bytes they are composed by all the strings that i sent when the ethernet is blocked (i think) and, when it unblock, i read all the bytes i sent in this blocked time.

if the datagram had been read correctly, where i wrote ----------------------, i would have seen "Discovery: dgram valid"

------------------------ : in this time the pc app sent the udp datagram.

if you need some other informations let me know it.

0 Kudos