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