yanvasilij wrote on Friday, February 03, 2017:
Hello Hein Tibosch,
Sorry for big pcap - my fault. I promise to compress next time )).
There is difficult to see time-outs in pcap because there is too much request. There is about one 100 ms time-out in about 100k-200k requests/response pairs. So I wrote simple python script that sends modbus request to my modbus slave and measures delay between request and response. If delay is bigger than 50 ms it write delay value to text file (delay value in seconds). So the log in attachments.
Within a TCP/Modbus connection, is it really necessary to poll so often?
Yes it is. There is nothing I can do with it.
By the way. Here code with socket processing. May something wrong there:
static void createSockets (void * eMBRegInputCB, void * eMBRegHoldingCB,
void * eMBRegCoilsCB, void * eMBRegDiscreteCB)
{
mbPollActivate = xSemaphoreCreateBinary();
/* task for all sockets are created and never deleted.
* They just blocks when sokets are closed */
for (u32 i = 0; i < NUM_OF_SOCKETS; i++)
{
socketTaskParams[i].queue = xQueueCreate (1, sizeof(Socket_t));
modbusTcp[i].eMBRegInputCB = (RegInputCBType)eMBRegInputCB;
modbusTcp[i].eMBRegHoldingCB = (RegHoldingCBType)eMBRegHoldingCB;
modbusTcp[i].eMBRegCoilsCB = (RegCoilsCBType)eMBRegCoilsCB;
modbusTcp[i].eMBRegDiscreteCB = (RegDiscreteCBType)eMBRegDiscreteCB;
socketTaskParams[i].modbusTcp = &modbusTcp[i];
socketTaskParams[i].modbusTcp->port.buf = socketTaskParams[i].buf;
socketTaskParams[i].isOppened = 0;
socketTaskParams[i].socketNum = i;
DEBUG_LOG(("creating socket task %d\r\n", socketTaskParams[i].socketNum ));
xTaskCreate( socketTask, "socketTask",
configMINIMAL_STACK_SIZE*10, &socketTaskParams[i], 2, &socketTaskHandle[i]);
}
}
/* sockets processing task */
static void socketTask (void *p)
{
static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 );
int32_t inlen;
Socket_t socket;
SocketTaskParams * params;
params = (SocketTaskParams*)p;
u8 connectionIsOppened = 0;
DEBUG_LOG(("socket %d task stated\r\n", params->socketNum));
for(;;)
{
xQueueReceive(params->queue, &socket, portMAX_DELAY);
FreeRTOS_setsockopt( socket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut,
sizeof( xReceiveTimeOut ) );
FreeRTOS_setsockopt( socket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut,
sizeof( xReceiveTimeOut ) );
DEBUG_LOG(("Socket %d oppened!\r\n", params->socketNum));
connectionIsOppened = 1;
while (connectionIsOppened)
{
params->modbusTcp->port.tcpInit(MB_TCP_PORT);
params->modbusTcp->port.addTcpSocket(socket);
inlen = FreeRTOS_recv(socket, params->modbusTcp->port.buf, MAX_MODBUS_TCP_FRAME_LEN, 0);
if (inlen)
{
params->modbusTcp->port.bufLen = inlen;
params->modbusTcp->event.post( EV_FRAME_RECEIVED );
u8 tmp[50];
memset(tmp, 0, 50);
// I just emulate response for 20 holding register request (so here no modbus stack processing at all)
tmp[0] = params->modbusTcp->port.buf[0];
tmp[1] = params->modbusTcp->port.buf[1];
tmp[2] = 0x00;
tmp[3] = 0x00;
tmp[4] = 0x00;
tmp[5] = 0x2B;
tmp[6] = 0x01;
tmp[7] = 0x03;
tmp[8] = 0x28;
FreeRTOS_send( socket, tmp, 49, 0);
}
if (inlen < 0)
{
connectionIsOppened = 0;
break;
}
}
FreeRTOS_shutdown( socket, FREERTOS_SHUT_RDWR );
do
{
if(FreeRTOS_recv(socket, params->modbusTcp->port.buf, MAX_MODBUS_TCP_FRAME_LEN, 0)<0)
break;
} while( 1 );
FreeRTOS_closesocket( socket );
params->isOppened = 0;
DEBUG_LOG(("Socket %d closed!\r\n", params->socketNum));
}
}
/* listenning task */
static void listeningTask (void *p)
{
static const TickType_t timeOut = portMAX_DELAY;
struct freertos_sockaddr bindAddress, clientParams;
Socket_t listenSocket, connectedSocket;
socklen_t clientParamsSize = sizeof( clientParams );
WinProperties_t xWinProps;
/* Fill in the buffer and window sizes that will be used by the socket. */
xWinProps.lTxBufSize = 300;
xWinProps.lTxWinSize = 2;
xWinProps.lRxBufSize = 300;
xWinProps.lRxWinSize = 2;
listenSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM,
FREERTOS_IPPROTO_TCP);
FreeRTOS_setsockopt( listenSocket, 0,
FREERTOS_SO_RCVTIMEO, &timeOut, sizeof(timeOut) );
FreeRTOS_setsockopt( listenSocket, 0, FREERTOS_SO_WIN_PROPERTIES,
( void * ) &xWinProps, sizeof( xWinProps ) );
bindAddress.sin_port = MB_TCP_PORT;
bindAddress.sin_port = FreeRTOS_htons( bindAddress.sin_port );
FreeRTOS_bind( listenSocket, &bindAddress, sizeof( bindAddress ) );
/* When connection established corresponding task is unblocked */
FreeRTOS_listen( listenSocket, NUM_OF_SOCKETS );
for (;;)
{
connectedSocket = FreeRTOS_accept (listenSocket, &clientParams,
&clientParamsSize);
runSocketTask (connectedSocket);
taskYIELD();
}
}
void initModbusTcpTask (void * eMBRegInputCB, void * eMBRegHoldingCB,
void * eMBRegCoilsCB, void * eMBRegDiscreteCB)
{
createSockets (eMBRegInputCB, eMBRegHoldingCB, eMBRegCoilsCB, eMBRegDiscreteCB);
xTaskCreate( listeningTask, "listeningTask", configMINIMAL_STACK_SIZE*10, NULL, 1, NULL);
}