rbos36 wrote on Thursday, January 11, 2018:
Hi, we have a pressing question about the FreeRTOS+TCP stack behaviour.
In our situation, we are sending data via TCP/IP from an embedded device to an Atom-based Linux machine.
The embedded device listens on a socket until the Linux machine connects, and then starts to send data chunks of around 1454 bytes every 4ms.
Using FREERTOS_SO_WIN_PROPERTIES
, we set TxBufSize
and TxWinSize
to 26 * MSS
(I’ll post a code snippet below).
However, in practice, the embedded device only sends 2 frames and then waits for an ACK to come in from the Linux machine before commencing, even if the advertised window has plenty of space.
What could be the cause?
Wireshark screen-shot; .89 is the embedded device ( see attachment )
Note that in the ~25ms before the ACK came in (highlighted row), the embedded device could have sent 25/4 = around 6 packets more, but it only sends two packets.
Here is the relevant code that creates the socket on the embedded device; do we set the FREERTOS_SO_WIN_PROPERTIES
at the right moment?
static Socket_t AcceptDataConnection(void)
{
static const TickType_t ACCEPT_TIME_OUT = portMAX_DELAY;
static const TickType_t RECV_TIME_OUT = 100 / portTICK_PERIOD_MS;
static const TickType_t SEND_TIME_OUT = 100 / portTICK_PERIOD_MS;
const BaseType_t TRUE = pdTRUE;
const BaseType_t BACKLOG = 0;
const uint16_t PORT_NUMBER = DATA_PORT;
struct freertos_sockaddr bindAddress, clientAddress;
Socket_t listeningSocket, connectedSocket;
socklen_t clientAddressSize = sizeof(clientAddress);
listeningSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
TlAssert(listeningSocket != FREERTOS_INVALID_SOCKET);
/* Set a time out so accept() will just wait for a connection. */
FreeRTOS_setsockopt(listeningSocket, 0, FREERTOS_SO_RCVTIMEO, &ACCEPT_TIME_OUT, sizeof(ACCEPT_TIME_OUT));
/* We only accept one simultaneous connection on the data port */
FreeRTOS_setsockopt(listeningSocket, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, &TRUE, sizeof(TRUE));
/* Bind the socket to the port that the gateway will connect to, then listen for incoming connections. */
bindAddress.sin_port = PORT_NUMBER;
bindAddress.sin_port = FreeRTOS_htons(bindAddress.sin_port);
FreeRTOS_bind(listeningSocket, &bindAddress, sizeof(bindAddress));
FreeRTOS_listen(listeningSocket, BACKLOG);
DBG("Listening for data connection on port %u" EOL, PORT_NUMBER);
/* Wait for a client to connect. */
connectedSocket = FreeRTOS_accept(listeningSocket, &clientAddress, &clientAddressSize);
TlAssert(connectedSocket != FREERTOS_INVALID_SOCKET);
/* Set socket timeouts */
FreeRTOS_setsockopt(connectedSocket, 0, FREERTOS_SO_RCVTIMEO, &RECV_TIME_OUT, 0);
FreeRTOS_setsockopt(connectedSocket, 0, FREERTOS_SO_SNDTIMEO, &SEND_TIME_OUT, 0);
/* Configure sliding window */
WinProperties_t xWinProps;
xWinProps.lTxBufSize = 26 * ipconfigTCP_MSS; /* Unit: bytes */
xWinProps.lTxWinSize = 26; /* Unit: MSS */
xWinProps.lRxBufSize = 4 * ipconfigTCP_MSS; /* Unit: bytes */
xWinProps.lRxWinSize = 2; /* Unit: MSS */
FreeRTOS_setsockopt(connectedSocket, 0, FREERTOS_SO_WIN_PROPERTIES, (void *) &xWinProps, sizeof(xWinProps));
DBG("New client connected to data port, starting acquisition" EOL);
return connectedSocket;
}
Thanks