AM2732: LWIP may have bugs,netconn_write netconn_write cannot transfer large amounts of data

Part Number: AM2732

Tool/software:

Hi,

I'm trying to transfer a large amount of data from Ethernet but failing.

I modified it according to this article, but it didn't work. 

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1173627/am2732-lwip-how-to-increase-the-max-transfer-size-for-netconn_write

The software version is mcu_plus_sdk_am273x_09_01_00_41

I tried to add below code in E:\ti\mmwave_mcuplus_sdk_04_06_00_01\mcu_plus_sdk_am273x_09_01_00_41\examples\networking\lwip\enet_cpsw_tcpclient\app_tcpclient.c and also failed to transfer the data successfully

#define APP_MAX_RX_DATA_LEN (200*1024U)

char snd_buf[APP_MAX_RX_DATA_LEN];

err = netconn_write(pConn, snd_buf, sizeof(snd_buf), NETCONN_COPY);

if (err == ERR_OK)
{
   printf("data was sent to the Server\r\n");
}
else
{
   DebugP_log("couldn't send packet to server\r\n");
}

After compilation and execution, the log information is as follows, but the network can be connected normally and no data can be received.Function netconn_write never returns.The task is abnormal

If the amount of data to be sent is changed to 10K bytes, it can be sent normally.

Modifying mcu_plus_sdk_am273x_09_01_00_41\source\networking\lwip\lwip-config\am273x\lwippools.h as shown below has no effect

code:

6710.app_tcpclient.c
/*
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 *
 * Author: Adam Dunkels <adam@sics.se>
 *
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include <string.h>
#include <stdio.h>
#include <kernel/dpl/TaskP.h>
#include <kernel/dpl/ClockP.h>
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include "enet_apputils.h"

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */
#define HOST_SERVER_IP6  ("FE80::12:34FF:FE56:78AB")

#define HOST_SERVER_PORT  (7)

#define APP_MAX_RX_DATA_LEN (200*1024U)

#define APP_NUM_ITERATIONS (2U)

#define APP_SEND_DATA_NUM_ITERATIONS (1U)

#define MAX_IPV4_STRING_LEN (20U)

char snd_buf[APP_MAX_RX_DATA_LEN];

/* ========================================================================== */
/*                         Structure Declarations                             */
/* ========================================================================== */

struct App_hostInfo_t
{
    ip_addr_t ipAddr;
    uint16_t port;
};

/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */
static void AppTcp_fillHostSocketInfo(struct App_hostInfo_t* pHostInfo);

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

static struct App_hostInfo_t gHostInfo;
static char   gHostServerIp4[MAX_IPV4_STRING_LEN] = "192.168.137.150";

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */


static void AppTcp_fillHostSocketInfo(struct App_hostInfo_t* pHostInfo)
{
    EnetAppUtils_print(" IP eneterd is: %s \r\n", gHostServerIp4);
    int32_t addr_ok;
    pHostInfo->port = HOST_SERVER_PORT;
    memset(&pHostInfo->ipAddr, 0, sizeof(pHostInfo->ipAddr));
    ip_addr_t*  pAddr = &pHostInfo->ipAddr;
    IP_SET_TYPE_VAL(*pAddr, IPADDR_TYPE_V4);
    addr_ok = ip4addr_aton(gHostServerIp4, ip_2_ip4(pAddr));
    EnetAppUtils_assert(addr_ok);

    return;
}


static void AppTcp_simpleclient(void *pArg)
{
    struct netconn *pConn = NULL;
    err_t err = ERR_OK, connectError = ERR_OK;
    struct App_hostInfo_t* pHostInfo = (struct App_hostInfo_t*) pArg;
    uint32_t buf_len = 0;
    const enum netconn_type connType = NETCONN_TCP;
    int frame_num = 0;

    for(int i= 0;i< sizeof(snd_buf);i++)
        snd_buf[i] = i;

    /* Create a new connection identifier. */
    //for (uint32_t pktIdx = 0; pktIdx < APP_NUM_ITERATIONS; pktIdx++)
    {
        struct netbuf *rxBbuf = NULL;
        pConn = netconn_new(connType);

        netconn_bind(pConn, IP_ADDR_ANY, HOST_SERVER_PORT);
        if (pConn != NULL)
        {
            /* Connect to the TCP Server */
            //EnetAppUtils_print("<<<< ITERATION %d >>>>\r\n", (pktIdx + 1));
            EnetAppUtils_print(" Connecting to: %s:%d \r\n", gHostServerIp4, HOST_SERVER_PORT);
            connectError = netconn_connect(pConn, &pHostInfo->ipAddr, pHostInfo->port);
            if (connectError != ERR_OK)
            {
                netconn_close(pConn);
                DebugP_log("Connection with the server isn't established\r\n");
                //continue;
            }

            DebugP_log("Connection with the server is established\r\n");

            while(1)
            {
                // send the data to the server
                //for (uint32_t i = 0; i < APP_SEND_DATA_NUM_ITERATIONS; i++)
                {
                    err = netconn_write(pConn, snd_buf, sizeof(snd_buf), NETCONN_COPY);
                    //err = netconn_write(pConn, snd_buf, sizeof(snd_buf), NETCONN_NOCOPY);

                    if (err == ERR_OK)
                    {
                        printf("data was sent to the Server\r\n");
                    }
                    else
                    {
                        DebugP_log("couldn't send packet to server\r\n");
                        continue;
                    }
                }
                DebugP_log("frame:%d \r\n",frame_num);
                frame_num++;
            }
            netconn_close(pConn);
            netconn_delete(pConn);
            DebugP_log("Connection closed\r\n");
            ClockP_sleep(1);
        }
    }
}

void AppTcp_showMenu(void)
{
    ip_addr_t ipAddr;
    int32_t addr_ok = 0;
    EnetAppUtils_print(" TCP Client Menu: \r\n");

    do
    {
        EnetAppUtils_print(" Enter TCP server IPv4 address:(example: 192.168.101.100)\r\n");
    //    DebugP_scanf("%s", gHostServerIp4);
        addr_ok = ip4addr_aton(gHostServerIp4, ip_2_ip4(&ipAddr));
    //    TaskP_yield();
    } while (addr_ok != 1);
}

void AppTcp_startClient(void)
{
    AppTcp_showMenu();
    AppTcp_fillHostSocketInfo(&gHostInfo);
    sys_thread_new("tcpinit_thread", AppTcp_simpleclient, &gHostInfo, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);

  /* USER CODE END 5 */
}

Thanks,

  • expert,

    I tested the mcu_plus_sdk_am273x_09_02_00_60 version sdk, and the enet_cpsw_tcpclient example still cannot send 700K data blocks continuously. It takes 350ms to send a packet. It won't take long for the program to become abnormal and no data will be output.

  • Hi Keynes,

    This seems to be an issue related to the LwIP memory configuration.

    1. Can you please share your lwipopts.h file? It will be located at: sdk/source/networking/lwip/lwip-config/lwipopts.h

    Seems like we need to modify the number of netconn pbufs available. The delays might be caused by packet buffers not being free or available which also explains the abnormal behaviour you see.

    2. Can you also halt your core (when you see the abnormal behaviour/data not being sent out”, go to the “expressions” window and search for “lwip_stats”. Here you can find members of stats object with prefix “mem”. Can you share those as well.

    Regards,

    Shaunak