TCP через lwIP возвращает только одну строку и обычно дает сбой после отправки 8 сообщений

Я пытаюсь реализовать интерфейс командной строки на MPC5748G, используя библиотеки, предоставленные в FreeRTOS. Я использую стек lwIP. Мне удалось запустить CLI с использованием UDP, однако я обнаружил две ошибки при реализации той же функциональности с TCP:

  • TCP-соединение перестает работать после отправки 8 команд.
  • независимо от значения pdFALSE по TCP распечатывается только одна строка. Если команда возвращает больше строк, распечатывается только первая.

Ни одной из этих ошибок не было при использовании UDP (код, который я написал, был очень похож). До сих пор я пытался разделить функции «прослушивания» и «ответа» на отдельные задачи, но это не решало проблему.

Кто-нибудь знает, почему задача зависает после получения 8 команд? Или, может быть, даже как распечатать больше строк? Насколько я понимаю, TCP-соединение все еще должно быть активным - есть отдельная функция, чтобы закрыть соединение, не удаляя его. Я не использую его здесь, поэтому - насколько я понимаю - я должен иметь возможность писать () для соединения, пока оно работает.

Код, который я использую:

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

person user7216373    schedule 26.12.2020    source источник


Ответы (1)


  1. Сбой.

Проблема заключалась в переполнении памяти - каждый новый nectonn_recv () выделял новый буфер. Проблема была решена добавлением netbuf_delete(pxRxBuffer); в конце цикла приема. Таким образом программа гарантирует, что память будет использована снова.

  1. На выходе только одна строка.

Эта проблема была решена путем отправки пустой строки в цикле. Добавление char test_data[1] = " "; netconn_write(pxNewConnection, test_data, 1, NETCONN_COPY); непосредственно перед выходом из цикла выполнения команды заставляло распечатывать все выходные строки. Я считаю, что эта проблема была на стороне клиента приложения.

  1. Дальнейшие ошибки.

В приведенном выше коде также есть еще одна ошибка - вызов netconn_accept () вызывает новое соединение каждый раз, когда он вызывается. Следовательно, возможно другое переполнение памяти, и в конце цикла приема необходимо вызвать netconn_close(pxNewConnection); netconn_delete(pxNewConnection);, чтобы освободить память.

person user7216373    schedule 18.01.2021