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 TickTypet ACCEPT
TIMEOUT = portMAX
DELAY;
static const TickTypet RECV
TIMEOUT = 100 / portTICK
PERIODMS;
static const TickType
t SENDTIME
OUT = 100 / portTICKPERIOD
MS;
const BaseTypet TRUE = pdTRUE;
const BaseType
t BACKLOG = 0;
const uint16t PORT
NUMBER = DATAPORT;
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