Reputation: 62
I am trying to implement a command line interface on MPC5748G using the libraries provided in FreeRTOS. I am using the lwIP stack. I managed to run the CLI using UDP, however I encounter two bugs when implementing the same functionality with a TCP:
None of these bugs were present when using UDP (the code I wrote was very similar). So far I tried separating the ‘listening’ and ‘respond’ functionality in separate tasks, but it does not solve the problem.
Does anybody have an idea why the task freezes after 8 commands have been recieved? Or maybe even how to get more lines printed out? A to my understanding the tcp connection should still be active - there is a separate function to close a connection without deleting it. I am not using it here, so - as far I understand - I should be able to write() to the connection as long as it is up.
The code I am using:
void vTCPCommandConsoleTask(void* pvParamaters){
struct netconn *pxNewConnection, *tcpconn;
struct netbuf *buf, *pxRxBuffer, *buf_send;
err_t connection_err, send_err, bind_err, listen_err, accept_err, recv_err;
ip_addr_t board_addr;
unsigned int payload_len;
char *data, *payload_data;
BaseType_t xMoreDataToFollow;
static signed char cOutputString[ configCOMMAND_INT_MAX_OUTPUT_SIZE ], cLocalBuffer[configCOMMAND_INT_MAX_OUTPUT_SIZE ];
/* create a new connection */
tcpconn = netconn_new(NETCONN_TCP);
/* bind the connection to a local IP */
IP4_ADDR((&board_addr.u_addr.ip4), netif_cfg[0]->ip_addr[0], netif_cfg[0]->ip_addr[1],netif_cfg[0]->ip_addr[2], netif_cfg[0]->ip_addr[3]);
bind_err = netconn_bind(tcpconn, &board_addr, SRC_PORT_NUM );
/* start listening and accept */
if (bind_err== ERR_OK) {
listen_err = netconn_listen(tcpconn);
for( ;; ){
accept_err = netconn_accept(tcpconn, &pxNewConnection);
if(accept_err == ERR_OK){
/*recieve the packet */
recv_err = netconn_recv(pxNewConnection, &pxRxBuffer);
if ( recv_err == ERR_OK ){
/* Get the payload and length */
payload_len = pxRxBuffer->p->len;
payload_data = pxRxBuffer->p->payload;
/* Copy the recieved message into the command string */
signed char cInputString[payload_len];
strncpy(cInputString, payload_data, payload_len);
/* create new buffers and send them for each line of the output */
do{
/*Pass the string to FreeRTOS+CLI. */
xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
/*create a buffer to send the data and fill it with output */
buf_send = netbuf_new();
data = netbuf_alloc(buf_send, sizeof(cOutputString));
memcpy(data, cOutputString, sizeof(cOutputString));
/* Send the output generated by the command's implementation. */
netconn_write( pxNewConnection, data , (u16_t) configCOMMAND_INT_MAX_OUTPUT_SIZE, NETCONN_COPY );
/* Free the buffer */
netbuf_delete(buf_send);
} while( xMoreDataToFollow != pdFALSE ); /* keep sending until the command does not generate any more output. */
} //recv_err == ERR_OK
} //accept_err
} //while(1)
} //bind_err
Upvotes: 0
Views: 1021
Reputation: 62
The problem was memory overflow - every new nectonn_recv() would allocate a new buffer. The problem has been solved by adding netbuf_delete(pxRxBuffer);
at the end of the receive loop. This way the program makes sure that the memory will be used over again.
This problem has been solved by sending an empty string, while in the loop. Adding
char test_data[1] = " "; netconn_write(pxNewConnection, test_data, 1, NETCONN_COPY);
just before exiting the command execution loop made all the output strings to get printed out. I believe that this problem was on the client's side of the application.
The code above also has another bug - the netconn_accept() call invokes a new connection every time it is called. Therefore another memory overflow can be possible, and a call to netconn_close(pxNewConnection); netconn_delete(pxNewConnection);
needs to be made at the end of the accept loop to free the memory.
Upvotes: 1