MQX 4.1 RTCS strange behaviour

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

MQX 4.1 RTCS strange behaviour

1,372 Views
igor-imx
Contributor IV

Hi Everyone

I just finished porting my project from MQX 4.0 to MQX 4.1. We are using a custom platform that is very close to TWRK60M512 tower board with some minor pinout differences.

I have a TCP client application (Modbus protocol client) which is working perfectly on the MQX4.0.

The client app is quite simple:

1. Connect to 6 servers using 6 sockets

2. Read the data (modbus tcp data) from those sockets

When i tired to run the same app after porting it (replacing the old MQX datatypes with the C99 style ones) and running it i get a really strange behaviour.

I attach a wireshark PCAP file which can explain it way better then with words. Basically after i Open 6 sockets and start reading the data, RTCS sends TCP RESET to the server.

So i made a test. I have called connect() 6 times with 6 different sockets  and paused the debugger right after that. All 6 sockets are opened, see attached picture.

After that, i have performed one Modbus TCP request to only the 1st socket. But the other 4 sockets were issued a TCP RESET command from RTCS and it is visible on the captured as well.

Can anyone shed any light on what might be going on there? I know for sure there are no stack smashed (i increased the stacks and it checked with TAD plugin, all at around 40%-65%).

Any help would be greatly appreciated.

Also, here are the socket options that i set to all of those 6 sockets:

VOID MBPTCPSetSockOptions(SOCKET iSocket)

{

  UINT option = 0;

  option = 5000;  

  ULONG retval = RTCS_OK;

  retval |= setsockopt(iSocket, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));

  option = 400; //380

  retval |= setsockopt(iSocket, SOL_TCP, OPT_RBSIZE, &option, sizeof(option));

  option = 400; //380

  retval |= setsockopt(iSocket, SOL_TCP, OPT_TBSIZE, &option, sizeof(option));  

  option = 1; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &option, sizeof(option));      

  option = 0; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));

  option = 1; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_RECEIVE_PUSH, &option, sizeof(option));

  option = 0; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_SEND_NOWAIT, &option, sizeof(option));

  option = 1; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_SEND_PUSH, &option, sizeof(option));

  option = 0; 

  //retval |= setsockopt(iSocket, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option));

  option = 100; 

  retval |= setsockopt(iSocket, SOL_TCP, OPT_RECEIVE_TIMEOUT, &option, sizeof(option));

  option = 30;   //30 seconds keep alive

  retval |= setsockopt(iSocket, SOL_TCP, OPT_KEEPALIVE, &option, sizeof(option));

  if(RTCS_OK != retval)

  {

    TASK_BLOCK();

  }

}

Thanks in advance

Tags (3)
0 Kudos
4 Replies

329 Views
igor-imx
Contributor IV

Sorry, forgot the attachments

0 Kudos

329 Views
igor-imx
Contributor IV

I found the problem and as always it was in our code

However there is one interesting observation:

Here is the code i use:

SOCKET iClientSocket[1] = SocketDescriptor i got from socket() function call

at this point connect() was called as well

recieving function:

SOCKET iResultSocket ;

while(!)

{

      iResultSocket = RTCS_selectset( iClientSocket , 1, 10);

      if (RTCS_SOCKET_ERROR == iResultSocket)

     {

           //hadle error close the socket

     }

     else

     {

          if(SELECT_TIMED_OUT == iResultSocket)

          {

              //sleep 1 MS and continue to the top of the loop

           }

           else

          {

               READ FROM THE SOCKET HERE.

               And this was the problem, since RTCS_selectset was returning a different socket value then the value of  iClientSocket[0].

              When i put the check here to see that iResultSocket ==  iClientSocket[0] and then do a read, problem disappeared

          }

     }

Can anyone on the MQX team please confirm that there is an issue with RTCS_selectset?

Thank you

0 Kudos

329 Views
Martin_
NXP Employee
NXP Employee

Hi,

I wonder if you enable RTCSCFG_SOCKET_OWNERSHIP ? The described issue might happen if RTCSCFG_SOCKET_OWNERSHIP is TRUE and the task is the owner of more sockets. A task is an owner of a socket if it creates it (a call to socket()).

Just a side note, current implementation of RTCS_selectset() function cannot distinguish between readability/writeability, so a socket can unblock RTCS_selectset() when an ACK has been received and the send buffer is empty (= it is writeable). So, perhaps you may need to put also a timeout for recv() and send() calls (a received ACK might unblock RTCS_select, and if your code calls recv() then, socket might not have any data for reading and recv() might block).

We re-designed select functionality for next version of MQX, so that MQX RTCS will support standard BSD-like select() on sockets. It is able to choose between read/write-abiltiy. For backward compatibility, RTCS_selectset() function will still be supported, but inside the stack, it will be implemented using the new select() function.

-Martin

0 Kudos

329 Views
igor-imx
Contributor IV

Hi Martin

Thank you for your reply

I have checked and the RTCSCFG_SOCKET_OWNERSHIP is disabled.

Unblocking of RTCS_select because of a write is probably what is happening since i have recv and send in different tasks.

0 Kudos