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
Solved! Go to Solution.
Hello
I found the problem
In fact, my modbus application could use some interface via SPI.
Then The SPI access was done via the same file on many task. In my case, one task was preempted by other. twice done SPI access.
When bug occurs, it caused by a task pre empted while SPI communication was in progress and the new task done also an access.
This should cause problem on Interrupt managment and then blocked some action like Ethernet...
:smileydevil:
Hello
I found the problem
In fact, my modbus application could use some interface via SPI.
Then The SPI access was done via the same file on many task. In my case, one task was preempted by other. twice done SPI access.
When bug occurs, it caused by a task pre empted while SPI communication was in progress and the new task done also an access.
This should cause problem on Interrupt managment and then blocked some action like Ethernet...
:smileydevil: