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