MCU-PLUS-SDK-AM243X: The App_shutdownNetworkStack function is not functioning properly.

Part Number: MCU-PLUS-SDK-AM243X

Tool/software: AM243X-EVM

Hello,

I am currently testing the dual-MAC functionality of icssg using the AM243x EVM.

Both Ethernet ports are in use, and the system is based on FreeRTOS.

In the simplest example, icssg tcpserver, the App_shutdownNetworkStack() function within the app_main.c file exists inside the appMain function.

However, it is located below an infinite loop and therefore never actually executes.

For the feature I'm developing, there are cases where I need to bring down the lwip stack.

I modified the code to exit the while(1) loop under specific conditions and then execute App_shutdownNetworkStack().

static void App_shutdownNetworkStack()
{
    for (uint32_t netifIdx = 0U; netifIdx < ENET_SYSCFG_NETIF_COUNT; netifIdx++)
    {
        LwipifEnetApp_netifClose(hlwipIfApp, NETIF_INST_ID0 + netifIdx);
    }
    return;
}

However, this function has the following issues:

1. The LwipifEnetApp_netifClose function called within this function invokes netif_remove.

The netif_remove function checks LWIP's core lock.

Therefore, calling this function directly causes the MCU to enter an infinite loop due to an assert.

So, I modified this function as follows.

static void App_shutdownNetworkStack()
{
    sys_lock_tcpip_core();  // Add for netif_remove
    
    for (uint32_t netifIdx = 0U; netifIdx < ENET_SYSCFG_NETIF_COUNT; netifIdx++)
    {
        LwipifEnetApp_netifClose(hlwipIfApp, NETIF_INST_ID0 + netifIdx);
    }
    
    sys_unlock_tcpip_core();    // Add for netif_remove
    return;
}

2. After calling the modified function, the first netif out of two appears to be removed normally.

However, when removing the second netif, it enters an infinite loop due to an assert.

The reason the second netif_remove enters an infinite loop can be found in the Lwip2Enet_close function within the lwip2enet.c file of the mcu+sdk.

The first part of this function is as follows.

void Lwip2Enet_close(Lwip2Enet_Handle hLwip2Enet, struct netif *netif)
{
    Lwip2Enet_assert(NULL != hLwip2Enet);

    /* Stop and delete the tick timer */
    ClockP_stop(&hLwip2Enet->pacingClkObj);
    ClockP_destruct(&hLwip2Enet->pacingClkObj);

    Lwip2Enet_netif_t* pInterface = Lwip2Enet_getInterfaceObj(hLwip2Enet, netif);
    
    .....
}

This function stops and releases the Clock of the pacingClkObj associated with the hLwip2Enet handle.

The problem is that the hLwip2Enet handle is not allocated per netif. This handle appears to exist as a single instance within LWIP.

** The Lwip2Enet_allocateObj function does not allocate an additional handle if hLwip2Enet is already allocated.

Therefore, the second `netif_remove` is called while the `pacingClkObj` of `hLwip2Enet` has already been removed during the first `netif_remove`.

At this point, since pacingClkObj is no longer valid, an assert causes an infinite loop.

Please fix this part.

Also, if there is a workaround that can be implemented before this is reflected in the next SDK release, please let me know.

Best Regards,

Jinwon Jang

  • Hi Jinwon Jang,

    This is a known issue that we identified within the feature set of LwIP interface. We are working on it to get it fixed. A partial implementation is currently available which you can test in your setup to deal with this. I am attaching a patch file to implement the same.

    Please note that there are few issues still persistent in the patch related to handling the flags properly. This is only a reference implementation, and is not a production-ready code which can be integrated into the final product.

    Please let us know if you face any issues verifying this implementation.

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/908/0001_2D00_all_2D00_socs_2D00_LwIP_2D00_Enet_2D00_Fix_2D00_LwIP_2D00_close_2D00_sequence.patch

    Regards,
    Teja.

  • Hi Teja,

    Thank you for your prompt reply.

    I'm writing because I encountered an issue while applying the patch file you attached.

    In appmain.c, there's a call to the killFlag function.

    However, the killFlag function cannot be found, causing a compilation error.

    Can you explain what this function does?

    Best regards,
    Jinwon Jang

  • Hi Jinwon Jang,

    Please let me check this on my end and send you the updated patch. Since the following 2 days are holidays in India, please expect a response on or before Monday.

    Thanks for your patience,

    Regards,
    Teja.