AnsweredAssumed Answered

MQX: Stack Ethernet: Send/Received blocked?

Question asked by arnogir on Mar 17, 2016
Latest reply on Mar 18, 2016 by arnogir

Hello

 

I'm using MQX 4.2 on a Kinetis K60.

 

In normal case, all work correctly: Ethernet Modbus is received, managed and response is done.

But sometime, When request is done so fast, at a moment, is blocked. Response is not done to a request, and new request not unblock the recv task.

Bellow is an extract of my code:

 

Initialization in a main task:

/* Allocates resources that RTCS needs and creates TCP/IP task. */ RTCS_create(); /* Read Board ID Number in NV Memory and then Get Mac Address */ ENET_get_mac_address(DV_ETH_ENET_DEVICE, MACLowAddress, DV_Eth_MacAddress); /* Initializes the Ethernet device, adds network interface, and sets up the IPCFG context for it. */ ipcfg_init_device(DV_ETH_ENET_DEVICE, DV_Eth_MacAddress); Error = ipcfg_bind_staticip(DV_ETH_ENET_DEVICE, &DV_Eth_IpData);      DV_Eth_TCPSocketAddr.sin_family       = AF_INET; DV_Eth_TCPSocketAddr.sin_port         = DV_Eth_iGetTCPRxTxPort(); DV_Eth_TCPSocketAddr.sin_addr.s_addr  = INADDR_ANY;  /* Create TCP socket */ DV_Eth_TCPSocketID = socket(PF_INET, SOCK_STREAM, 0); /* Bind TCP socket */ bind(DV_Eth_TCPSocketID, &DV_Eth_TCPSocketAddr, sizeof(DV_Eth_TCPSocketAddr)); /* Listen on TCP port */ listen(DV_Eth_TCPSocketID, 0);  DV_Eth_TCPClientSocketID = accept(DV_Eth_TCPSocketID, &DV_Eth_TCPClientSocketAddr, &DV_Eth_TCPClientSocketAddrLen);   /* Set socket options */ Option = TRUE;      setsockopt(DV_Eth_TCPClientSocketID, SOL_TCP, OPT_SEND_NOWAIT, &Option, sizeof(Option)); setsockopt(DV_Eth_TCPClientSocketID, SOL_TCP, OPT_SEND_PUSH, &Option, sizeof(Option));

 

 

In a receive task, which is always in blocked state and run as soon as satagram is received:

Task: while(1) {  ReadSize = recv(DV_Eth_TCPClientSocketID, BufferPtr, BufferSize, 0);   /* Applciation data managment (Ethernet Modbus) */  Note : This part can call DV_Eth_SendMsg to make a ModBus response  [...] }

 

internal function DV_Eth_SendMsg:

uint32_t DV_Eth_SendMsg(uint8_t *BufferPtr, uint32_t BufferSize) {      int32_t WriteSize = 0;   WriteSize = send(DV_Eth_TCPClientSocketID, BufferPtr, BufferSize, 0);     return((uint32_t)WriteSize); }

 

Bellow is WireShark trace:

Computer is 192.168.1.150

Target Kinetis K60 with MQX is 192.168.1.156

No.     Time                          Source                Destination           Protocol Length Info
Computer done a Modbus request to the target:
15602 2016-03-16 17:22:02.537174    192.168.1.150         192.168.1.156         Modbus/TCP 66        Query: Trans:  3367; Unit:   0, Func:   3: Read Holding Registers
15603 2016-03-16 17:22:02.537504    192.168.1.156         192.168.1.150         TCP      60     502 → 57053 [PSH, ACK] Seq=68344 Ack=56683 Win=3178 Len=0
Target make a response : Ok
15604 2016-03-16 17:22:02.545654    192.168.1.156         192.168.1.150         Modbus/TCP 81     Response: Trans:  3367; Unit:   0, Func:   3: Read Holding Registers
15605 2016-03-16 17:22:02.545747    192.168.1.150         192.168.1.156         TCP      54     57053 → 502 [ACK] Seq=56683 Ack=68371 Win=63492 Len=0
 
 
 
Computer done a Modbus request to the target: 
15606 2016-03-16 17:22:02.583458    192.168.1.150         192.168.1.156         Modbus/TCP 66        Query: Trans:  3367; Unit:   0, Func:   3: Read Holding Registers
15607 2016-03-16 17:22:02.583966    192.168.1.156         192.168.1.150         TCP      60     502 → 57053 [PSH, ACK] Seq=68371 Ack=56695 Win=3166 Len=0
Target ACK the request, but my applciation Recv Task is always blocked necause wait datagram, So No Target response !!!!! NOK !!!!!

Computer done a newly Modbus request to the target:
15608 2016-03-16 17:22:02.619075    192.168.1.150         192.168.1.156         Modbus/TCP 66        Query: Trans:  3367; Unit:   0, Func:   3: Read Holding Registers
15609 2016-03-16 17:22:02.619584    192.168.1.156         192.168.1.150         TCP      60     502 → 57053 [PSH, ACK] Seq=68371 Ack=56707 Win=3154 Len=0
Target ACK the request, but no response
Etc...

In parrallale I have a task which detect cable deconnect:

(simplified code):

 

 

if (ipcfg_get_link_active(DV_ETH_ENET_DEVICE) == FALSE) {  printf("Cable disconnected\n");         printf("\nWaiting for ethernet cable plug in ...\n");  /* Close TCP socket */  DV_Eth_iTCPState = DV_ETH_TCP_WAIT_CONNECT;  DV_Eth_iCloseSocket(DV_Eth_TCPClientSocketID);  ....    if (ipcfg_get_link_active(DV_ETH_ENET_DEVICE) == TRUE)   {   /* Wait new connection */   DV_Eth_TCPClientSocketID = accept(DV_Eth_TCPSocketID, &DV_Eth_TCPClientSocketAddr, &DV_Eth_TCPClientSocketAddrLen);     /* Set socket options */   Option = TRUE;        setsockopt(DV_Eth_TCPClientSocketID, SOL_TCP, OPT_SEND_NOWAIT, &Option, sizeof(Option));   setsockopt(DV_Eth_TCPClientSocketID, SOL_TCP, OPT_SEND_PUSH, &Option, sizeof(Option));  } }

 

 

if I made a cable deconnection/deconnection, socket is reinitialized, but problem still present. Is is mandatory to Reset the µC to make a new MQX init.

 

Is somebody has an Idea, what can I read to try to found where come from my problem? Is any internal MQX status or flag to read can help me to found where the problem come from?

I have a problem in my code?

 

Thank

(Note :   complete source code is provided with this post)

Original Attachment has been moved to: DV_Eth.c.zip

Outcomes