LwIP Netconn API + FreeRTOS проблема с буфером TCP-клиента

Я пытался изменить пример tcp-сервера с LwIP на плате STM32F4DISCOVERY. Я должен написать отправителя, который не обязательно должен отвечать на ответы сервера. Например, он может отправлять данные с частотой 100 мс.

Во-первых, пример TCP-сервера выглядит так:

static void tcpecho_thread(void *arg)
{
  struct netconn *conn, *newconn;
  err_t err;

  LWIP_UNUSED_ARG(arg);

  /* Create a new connection identifier. */
  conn = netconn_new(NETCONN_TCP);

  if (conn!=NULL) {  
    /* Bind connection to well known port number 7. */
    err = netconn_bind(conn, NULL, DEST_PORT);

    if (err == ERR_OK) {
      /* Tell connection to go into listening mode. */
      netconn_listen(conn);

      while (1) {
        /* Grab new connection. */
        newconn = netconn_accept(conn);

        /* Process the new connection. */
        if (newconn) {
          struct netbuf *buf;
          void *data;
          u16_t len;

          while ((buf = netconn_recv(newconn)) != NULL) {
            do {
              netbuf_data(buf, &data, &len);

              //Incoming package
              .....

              //Check for data
              if (DATA IS CORRECT) 
              {
                //Reply
                data = "OK";
                len = 2;

                netconn_write(newconn, data, len, NETCONN_COPY);
              }

            } while (netbuf_next(buf) >= 0);

            netbuf_delete(buf);
          }

          /* Close connection and discard connection identifier. */
          netconn_close(newconn);
          netconn_delete(newconn);
        }
      }
    } else {
      printf(" can not bind TCP netconn");
    }
  } else {
    printf("can not create TCP netconn");
  }
}

Я изменил этот код, чтобы получить клиентскую версию, вот что у меня есть на данный момент:

static void tcpecho_thread(void *arg)
{
  struct netconn *xNetConn = NULL;

  struct ip_addr local_ip; 
  struct ip_addr remote_ip; 
  int rc1, rc2; 

  struct netbuf *Gonderilen_Buf = NULL;
  struct netbuf *gonderilen_buf = NULL;
  void *b_data;
  u16_t b_len;

  IP4_ADDR( &local_ip, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3 );  
  IP4_ADDR( &remote_ip, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );

  xNetConn = netconn_new ( NETCONN_TCP );  
  rc1 = netconn_bind ( xNetConn, &local_ip, DEST_PORT ); 
  rc2 = netconn_connect ( xNetConn, &remote_ip, DEST_PORT );

  b_data = "+24C"; // Data to be send
  b_len = sizeof ( b_data );  

   while(1)
   {
     if ( rc1 == ERR_OK )
      {
        // If button pressed, send data "+24C" to server
        if (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET)
        {

          Buf = netbuf_new();
          netbuf_alloc(Buf, 4); // 4 bytes of buffer
          Buf->p->payload = "+24C";
          Buf->p->len = 4;

          netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);
          vTaskDelay(100); // To see the result easily in Comm Operator

          netbuf_delete(Buf);
        }
    }
    if ( rc1 != ERR_OK || rc2 != ERR_OK )
    {
      netconn_delete ( xNetConn );
    }
  }
}

Пока выполняется операция записи, netconn_write отправляет то, что находится в его буфере. Неважно, является ли b_data NULL или нет. Я проверил это, добавив строчку b_data = NULL;

Таким образом, результат в Comm Operator будет таким:

Rec:(02:47:27)+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C

Однако я хочу, чтобы это работало так:

Rec:(02:47:22)+24C
Rec:(02:47:27)+24C 
Rec:(02:57:12)+24C 
Rec:(02:58:41)+24C

Желаемая операция записи происходит, когда я жду примерно 8 секунд, прежде чем снова нажимать кнопку.

Поскольку функция netconn_write не разрешает запись в буфер, я не могу его очистить. И netconn_send разрешен только для UDP-соединений.

Мне нужно руководство, чтобы понять проблему и найти решение. Любая помощь будет принята с благодарностью.


person mozcelikors    schedule 16.01.2014    source источник


Ответы (2)


Просто нужно правильно распечатать результат.

Вы можете попробовать добавить эту часть кода перед записью в структуру данных netbuf:

char buffer[20]; 

sprintf(buffer,"24+ \n");

Buf->p->payload = "+24C";
person Riccardo    schedule 22.11.2016

Я вижу одну или две проблемы в вашем коде, в зависимости от того, что именно вы хотите. Во-первых, вы отправляете не b_data, а постоянную строку:

b_data = "+24C"; // Data to be send

а потом

Buf->p->payload = "+24C";
Buf->p->len = 4;
netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);

b_data там нигде не упоминается. Отправлено payload. Попробуйте Buf->p->payload = b_data;, если вы этого хотите.

Во-вторых, если вы хотите, чтобы текст +24C отправлялся только один раз, когда вы нажимаете кнопку, вам понадобится цикл, чтобы ждать, пока кнопка снова откроется, прежде чем продолжить цикл, или он будет отправлять +24C непрерывно, пока вы не перестанете нажимать кнопка. Что-то в этом направлении:

while (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET) {
  vTaskDelay(1);
}
person Ale    schedule 16.10.2017