This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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:

/*
 * 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

  • Hi Shaunak,

    1. I uploaded the lwipopts.h file.This configuration works normally in the mmwave_mcuplus_sdk_04_02_00_03 version SDK.

    lwippools.h

    2.The first time I set the data length to be transmitted to 800K, and then send a packet every 450ms, TCP can establish a connection normally,but no data output. When the program is running, CCS debug, select "Continues Refresh" mem information as shown below

    When I halt the core ,mem information is as follows:

    I run it several times and the error message value was changing。

    3.A packet of 8K data is selected to send, and the delay after sending 100 packets is 450ms。

    After sending 258M data, the network became abnormal. I halted the core. The screenshot is as follows:

    4. I uploaded the modified file. The changes are very small. You can download it directly to reproduce the problem.

    /*
     * 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 (8*1024U)
    
    #define APP_NUM_ITERATIONS (2U)
    
    #define APP_SEND_DATA_NUM_ITERATIONS (100U)
    
    #define MAX_IPV4_STRING_LEN (200U)
    
    char snd_buf[APP_MAX_RX_DATA_LEN] = {0};
    
    /* ========================================================================== */
    /*                         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,%d\r\n",TCP_DEBUG);
    
                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:%d\r\n",err);
                            //continue;
                        }
                    }
                    //DebugP_log("frame:%d \r\n",frame_num);
    
                    vTaskDelay(450);
                    //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.137.150)\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 */
    }
    
    /*
     * Copyright (c) 2001,2002 Florian Schulze.
     * 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. Neither the name of the authors nor the names of the contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``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 AUTHORS OR CONTRIBUTORS 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.
     *
     * app_main.c - This file is part of lwIP test
     *
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <stdio.h>
    #include <stdarg.h>
    #include <string.h>
    #include "FreeRTOS.h"
    #include "task.h"
    /* lwIP core includes */
    #include "lwip/opt.h"
    #include "lwip/sys.h"
    #include "lwip/tcpip.h"
    #include "lwip/dhcp.h"
    
    #include <kernel/dpl/TaskP.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/ClockP.h>
    #include <networking/enet/utils/include/enet_apputils.h>
    #include <networking/enet/utils/include/enet_board.h>
    #include "ti_board_config.h"
    #include "ti_board_open_close.h"
    #include "ti_drivers_open_close.h"
    #include "ti_enet_config.h"
    #include "ti_enet_open_close.h"
    #include "app_cpswconfighandler.h"
    #include "app_tcpclient.h"
    #include "ti_enet_lwipif.h"
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    static const uint8_t BROADCAST_MAC_ADDRESS[ENET_MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    static void App_printCpuLoad();
    
    static void App_tcpipInitCompleteCb(void *pArg);
    
    static void App_setupNetif();
    
    static void App_allocateIPAddress();
    
    static void App_setupNetworkStack();
    
    static void App_shutdownNetworkStack();
    
    static void App_netifStatusChangeCb(struct netif *state_netif);
    
    static void App_netifLinkChangeCb(struct netif *state_netif);
    
    static inline int32_t App_isNetworkUp(struct netif* netif_);
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    /* dhcp struct for the ethernet netif */
    static struct dhcp g_netifDhcp[ENET_SYSCFG_NETIF_COUNT];
    struct netif *g_pNetif[ENET_SYSCFG_NETIF_COUNT];
    
    /* Handle to the Application interface for the LwIPIf Layer
     */
    LwipifEnetApp_Handle hlwipIfApp = NULL;
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    
    int appMain(void *args)
    {
        Enet_Type enetType;
        uint32_t instId;
    
    
        sys_sem_t pWaitSem;
        const err_t err = sys_sem_new(&pWaitSem, 0);
        EnetAppUtils_assert(err == ERR_OK);
    
        Drivers_open();
        Board_driversOpen();
    
        DebugP_log("==========================\r\n");
        DebugP_log("  CPSW LWIP TCP CLIENT    \r\n");
        DebugP_log("==========================\r\n");
    
        EnetApp_getEnetInstInfo(CONFIG_ENET_CPSW0, &enetType, &instId);
    
        EnetAppUtils_enableClocks(enetType, instId);
    
        EnetApp_driverInit();
    
        const int32_t status = EnetApp_driverOpen(enetType, instId);
        if (ENET_SOK != status)
        {
            EnetAppUtils_print("Failed to open ENET: %d\r\n", status);
            EnetAppUtils_assert(false);
            return -1;
        }
    
        EnetApp_addMCastEntry(enetType,
                              instId,
                              EnetSoc_getCoreId(),
                              BROADCAST_MAC_ADDRESS,
                              CPSW_ALE_ALL_PORTS_MASK);
    
        App_setupNetworkStack();
    
        while (false == App_isNetworkUp(netif_default))
        {
            DebugP_log("Waiting for network UP ...\r\n");
            ClockP_sleep(2);
        }
    
        DebugP_log("Network is UP ...\r\n");
        ClockP_sleep(1);
        AppTcp_startClient();
    
        sys_sem_wait(&pWaitSem);
        while (1)
        {
            ClockP_usleep(3000);
            App_printCpuLoad();
        }
    
        App_shutdownNetworkStack();
        return 0;
    }
    
    static void App_setupNetworkStack()
    {
        sys_sem_t pInitSem;
        const err_t err = sys_sem_new(&pInitSem, 0);
        EnetAppUtils_assert(err == ERR_OK);
    
        tcpip_init(App_tcpipInitCompleteCb, &pInitSem);
    
        /* wait for TCP/IP initialization to complete */
        sys_sem_wait(&pInitSem);
        sys_sem_free(&pInitSem);
    
        return;
    }
    
    static void App_shutdownNetworkStack()
    {
        LwipifEnetApp_netifClose(hlwipIfApp, NETIF_INST_ID0);
        return;
    }
    
    static void App_tcpipInitCompleteCb(void *pArg)
    {
        sys_sem_t *pSem = (sys_sem_t*)pArg;
        EnetAppUtils_assert(pArg != NULL);
    
        /* init randomizer again (seed per thread) */
        srand((unsigned int)sys_now()/1000);
    
        App_setupNetif();
    
        //App_allocateIPAddress();
    
        sys_sem_signal(pSem);
    }
    
    static void App_setupNetif()
    {
        ip4_addr_t ipaddr, netmask, gw;
    
        ip4_addr_set_zero(&gw);
        ip4_addr_set_zero(&ipaddr);
        ip4_addr_set_zero(&netmask);
    
    
        //set evm net info
        IP_ADDR4(&ipaddr,192,168,137,120);
        IP_ADDR4(&netmask,255,255,255,0);
        IP_ADDR4(&gw,192,168,137,1);
    
        DebugP_log("Starting lwIP, local interface IP is dhcp-enabled\r\n");
        hlwipIfApp = LwipifEnetApp_getHandle();
        for (uint32_t i = 0U; i < ENET_SYSCFG_NETIF_COUNT; i++)
        {
            /* Open the netif and get it populated*/
            g_pNetif[i] = LwipifEnetApp_netifOpen(hlwipIfApp, NETIF_INST_ID0 + i, &ipaddr, &netmask, &gw);
            netif_set_status_callback(g_pNetif[i], App_netifStatusChangeCb);
            netif_set_link_callback(g_pNetif[i], App_netifLinkChangeCb);
            netif_set_up(g_pNetif[NETIF_INST_ID0 + i]);
        }
        LwipifEnetApp_startSchedule(hlwipIfApp, g_pNetif[ENET_SYSCFG_DEFAULT_NETIF_IDX]);
    }
    
    static void App_allocateIPAddress()
    {
        sys_lock_tcpip_core();
        for (uint32_t  i = 0U; i < ENET_SYSCFG_NETIF_COUNT; i++)
        {
            dhcp_set_struct(g_pNetif[NETIF_INST_ID0 + i], &g_netifDhcp[NETIF_INST_ID0 + i]);
    
            const err_t err = dhcp_start(g_pNetif[NETIF_INST_ID0 + i]);
            EnetAppUtils_assert(err == ERR_OK);
        }
        sys_unlock_tcpip_core();
        return;
    }
    
    static void App_netifStatusChangeCb(struct netif *pNetif)
    {
        if (netif_is_up(pNetif))
        {
            DebugP_log("Enet IF UP Event. Local interface IP:%s\r\n",
                        ip4addr_ntoa(netif_ip4_addr(pNetif)));
        }
        else
        {
            DebugP_log("Enet IF DOWN Event\r\n");
        }
        return;
    }
    
    static void App_netifLinkChangeCb(struct netif *pNetif)
    {
        if (netif_is_link_up(pNetif))
        {
            DebugP_log("Network Link UP Event\r\n");
        }
        else
        {
            DebugP_log("Network Link DOWN Event\r\n");
        }
        return;
    }
    
    static int32_t App_isNetworkUp(struct netif* netif_)
    {
        return (netif_is_up(netif_) && netif_is_link_up(netif_) && !ip4_addr_isany_val(*netif_ip4_addr(netif_)));
    }
    
    static void App_printCpuLoad()
    {
        static uint32_t startTime_ms = 0;
        const  uint32_t currTime_ms  = ClockP_getTimeUsec()/1000;
        const  uint32_t printInterval_ms = 5000;
    
        if (startTime_ms == 0)
        {
            startTime_ms = currTime_ms;
        }
        else if ( (currTime_ms - startTime_ms) > printInterval_ms )
        {
            const uint32_t cpuLoad = TaskP_loadGetTotalCpuLoad();
    
            DebugP_log(" %6d.%3ds : CPU load = %3d.%02d %%\r\n",
                        currTime_ms/1000, currTime_ms%1000,
                        cpuLoad/100, cpuLoad%100 );
    
            startTime_ms = currTime_ms;
            TaskP_loadResetAll();
        }
        return;
    }
    

    There are two modifications in the syscfg file, as shown below:

    The left side is the modified code, and the right side is the original code

    Thank you very much, looking forward to your reply

  • This test sends 4K data per packet, sends 20 packets continuously, then delays 450ms and halts the core. The screenshots are as follows:

    Screenshot shows LwIP memory is exhausted。Sending different amounts of data causes different phenomena. When sending 800K at a time, LwIP memory is not exhausted (the second screenshot above), but there is no data output at all. There may be different bugs.

  • Hi Keynes,

    • The MSS L2 memory on AM273x is about 950KB and The DSS L3 memory is about 3.5MB in the default out of box example.
    • The issue here is very clear, we are running out of memory. Now the LwIP-stack takes care of freeing up the netbufs (network buffers which hold the packets). Seems like when trying to send out a lot of data, the network buffers are not being freed at a rate faster than which they are used, so at a certain point, we run out of netbufs and thus the program crashes. Now, we cannot increase the LwIP Memory pools to a very high number since the memory we have is limited. We can also try to increase the TCP segment or window size so we handle more data.

    Q. Can you pleas check if the application work if you do not change the memory locations as shared above in syscfg?

    Q. In the following file (which configures the LwIP stack, mcu_plus_sdk/source/networking/lwip/lwip-config/am273x/lwipopts.h , please try increasing the Netconn TCP macros "MEMP_NUM_NETBUF", "MEMP_NUM_TCPIP_MSG_API", "TCP_SND_BUF"

    Increase the MACROS keeping in mind the following calculations:

    • TCP_SND_BUF < (2 * TCP_MSS)
    • TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
    • TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN

    After the above change, please rebuild the LwIP library as follows:

    #CLEAN
    gmake -sj -f makefile.am273x lwip-contrib_r5f.ti-arm-clang_clean PROFILE=debug
    gmake -sj -f makefile.am273x lwip-freertos_r5f.ti-arm-clang_clean PROFILE=debug
    
    #BUILD
    gmake -sj -f makefile.am273x lwip-contrib_r5f.ti-arm-clang PROFILE=debug
    gmake -sj -f makefile.am273x lwip-freertos_r5f.ti-arm-clang PROFILE=debug

    Then, rebuild your example and test again. 

    Regards,
    Shaunak

  • Hi Shaunak,

    1.I restored the syscfg to the original files in the SDK. Then compile and test it .If I send a packet of 800KB in length, the data will stop after a while, which should be because the netbufs is exhausted.I doubled the values ​​of the three parameters of Netconn TCP macros "MEMP_NUM_NETBUF", "MEMP_NUM_TCPIP_MSG_API", and "TCP_SND_BUF", and the phenomenon is still the same.As you said, The DSS L3 memory is about 3.5MB in the default out of box example. I plan to set the LwIP Memory pools to 1MB. Is it possible to send packets with a data length of 800KB?

    #define TCP_SND_BUF         (44 * TCP_MSS)
    The maximum value of TCP_SND_BUF can be set to (44 * TCP_MSS).The maximum value that can be set is 64KB. If add more compilation, an error will be reported, prompting: F:/ti/mmwave_mcuplus_sdk_04_06_00_01/mcu_plus_sdk_am273x_09_01_00_41/source/networking/lwip/lwip-stack/src/core/init.c:151: 2: error: "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" 
    The value of TCP_SND_BUF is set to (32 * TCP_MSS), which is more stable than setting it to (44 * TCP_MSS). This phenomenon is also very strange.
    What should I do next? If the chip performance is not good enough, why can the old version of SDK realize this function?

    The MCU SDK version included in mmwave_mcuplus_sdk_04_02_00_03 is mcu_plus_sdk_am273x_08_02_00_26.In mmwave_mcuplus_sdk_04_02_00_03, we successfully sent a packet of 800KB test data in 1000ms. I think enet_cpsw_tcpclient demo can definitely send a packet of 800KB data in 1000ms.

    2.

    • TCP_SND_BUF < (2 * TCP_MSS)
    • TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
    • TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN

    Is the operator symbol of this rule wrong?The sdk source code is defined as follows:

    #define TCP_SND_BUF           (16 * TCP_MSS)
    #define TCP_SND_QUEUELEN       (8 * TCP_SND_BUF/TCP_MSS)
    #define TCP_SNDLOWAT           (TCP_SND_BUF/2)
    The above definition conflicts with the rules you mentioned.
  • Hi Keynes, 

    Apologies for a delayed response.

    I was able to test sending 100KB of data. I'm still trying to configure the memory correctly to reach the goal of 800KB data transfer. When we compare the 08.02 SDK vs the 09.01 SDK, there have been significant changes related to memory and pbufs in lwip stack. We have implemented custom Rx pbufs and changed the memory allocation. Please allow me a few business days to look into this and get back.

    Regards,

    Shaunak

  • Hi Shaunak

    Thank you for your reply. When testing 800KB data packets, you can send them multiple times and for a long time to confirm the stability. Thank you very much for your help.

  • Hi Shaunak

    Half a month has passed. Is there a solution? Can the code be optimized?