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.

The usage rate of MCU's CPU rised sharply after abnormal network interruption and reconnection.

Part Number: AM243x-lp

Tool/software:

When using AM243x-lp as a client to do TCP/IP communication, it was found that the abnormal interruption(unplug the network cable or power off the server device) would cause the usage rate of MCU's CPU to rise sharply, from the original 3%+ to 20%+. The code is modified based on ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk\examples\networking\lwip\enet_cpsw_socket, which still uses the socket interface of LwIP. The server side runs on another development board. If the socket is opened and closed normally, the usage rate of MCU's CPU will not increase. If unplug the network cable or power off the server device, wait more than 8 seconds and then restore, the usage rate of MCU'CPU will rise from 3%+ to 20%+ after reconnecting. I also developed a linux version client and does the same thing, the CPU usage rate of running linux machine does not increase, so I think it is not a server side issue, it is probably a network protocol stack or network driver issue. Below is my test code on AM243x-lp.

static void AppSocket_simpleClient(void* pArg)
{
static const uint8_t LOGIN_MSG[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x10, 0x14, 0x01, 0x00, 0x04, 0x08, // login
0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38}; // write 8888 8888, from address 5121

static const uint8_t READ_COMM_TIMEOUT_MSG[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x14, 0x4e, 0x00, 0x01}; // read 5195, Com time out for M100

static const uint8_t READ_UP_TIME_MSG[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x15, 0x87, 0x00, 0x02}; // read 5511 up time for M100

struct sockaddr* pAddr = pArg;
int32_t sock = -1, ret = 0;
struct timeval opt = {0}, tv = {0};
fd_set readset = {0}, writeset = {0}, errset = {0};

for (uint32_t i = 0; i < APP_SOCKET_NUM_ITERATIONS; i++)
{
//EnetAppUtils_print("<<< Iteration %d >>>> \r\n", i+1);
EnetAppUtils_print(" Connecting to: %s:%d \r\n", gHostServerIp4, SOCK_HOST_SERVER_PORT);
if (netstate == 0)
{
ClockP_usleep(4000000);
continue;
}
/* create the socket */
sock = lwip_socket(pAddr->sa_family, SOCK_STREAM, 0);
if (sock < 0)
{
EnetAppUtils_print("ERR: unable to open socket\r\n");
continue;
}

/* connect */
ret = lwip_connect(sock, pAddr, pAddr->sa_len);
if (ret != 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: unable to connect\r\n");
continue;
}
EnetAppUtils_print("Connected to host\r\n");

/* set recv timeout (100 ms) */
opt.tv_sec = 0;
opt.tv_usec = 100 * 1000;
ret = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(opt));
if (ret != 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: set sockopt failed\r\n");
continue;
}

/*login rf modulator*/
ret = lwip_write(sock, LOGIN_MSG, sizeof(LOGIN_MSG));
if (ret != sizeof(LOGIN_MSG))
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket write failed for login rf modulator.\r\n");
continue;
}

ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
if (ret <= 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket read failed for login rf modulator.\r\n");
continue;
}

for (uint32_t i=0; i<160; i++)
{
EnetAppUtils_print("Cycle number %d\r\n", i);
ret = lwip_write(sock, READ_COMM_TIMEOUT_MSG, sizeof(READ_COMM_TIMEOUT_MSG));
if (ret != sizeof(READ_COMM_TIMEOUT_MSG))
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: READ_COMM_TIMEOUT_MSG failed\r\n");
continue;
}

ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
if (ret <= 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: READ_COMM_TIMEOUT_MSG failed\r\n");
continue;
}

ret = lwip_write(sock, READ_UP_TIME_MSG, sizeof(READ_UP_TIME_MSG));
if (ret != sizeof(READ_UP_TIME_MSG))
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: READ_UP_TIME_MSG failed\r\n");
continue;
}

ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
if (ret <= 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: READ_UP_TIME_MSG failed\r\n");
continue;
}

ClockP_usleep(100000);
}
#if 0
/* Send data to Host */
ret = lwip_write(sock, APP_CLIENT_TX_MSG1, sizeof(APP_CLIENT_TX_MSG1));
if (ret != sizeof(APP_CLIENT_TX_MSG1))
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket write failed\r\n");
continue;
}
EnetAppUtils_print("Message to host: %s\r\n", APP_CLIENT_TX_MSG1);

FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_ZERO(&errset);
FD_SET(sock, &readset);
FD_SET(sock, &writeset);
FD_SET(sock, &errset);
tv.tv_sec = 1;
tv.tv_usec = 0;
ret = lwip_select(sock + 1, &readset, &writeset, &errset, &tv);
if (ret <= 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket select failed\r\n");
continue;
}
EnetAppUtils_assert(!FD_ISSET(sock, &errset));

if (FD_ISSET(sock, &readset))
{
ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
if (ret <= 0)
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket read failed\r\n");
continue;
}
gRxDataBuff[ret] = '\0';
EnetAppUtils_print("Message from host: %s\r\n", gRxDataBuff);
}
if (FD_ISSET(sock, &writeset))
{
ret = lwip_write(sock, APP_CLIENT_TX_MSG2, sizeof(APP_CLIENT_TX_MSG2));
if (ret != sizeof(APP_CLIENT_TX_MSG2))
{
ret = lwip_close(sock);
EnetAppUtils_print("ERR: socket write failed!\r\n");
continue;
}
EnetAppUtils_assert(ret == sizeof(APP_CLIENT_TX_MSG2));
EnetAppUtils_print("Message to host: %s\r\n", APP_CLIENT_TX_MSG2);
}
#endif
/* close */
ret = lwip_close(sock);
EnetAppUtils_print("Closed Socket connection\r\n");
ClockP_usleep(8000000);
}
return;
}

  • Hi ,

    Thanks for your query.

    Can you help me with steps to follow to reproduce the issue on my setup?
    Which SDK example should I use?
    What are local changes I need to do on application side?

    Regards

    Ashwani

  • Hi Ashwani,

    ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk\examples\networking\lwip\enet_cpsw_socket, this is the demo I used, you can find it in  ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk.

    I only changed app_socket.c and app_main.c. see below code.

    /*
     * Copyright (c) 2017 Simon Goldschmidt
     * 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: Simon Goldschmidt <goldsimon@gmx.de>
     *
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    #include "app_socket.h"
    #include "lwip/opt.h"
    #include "lwip/sockets.h"
    #include "lwip/sys.h"
    
    #include <string.h>
    #include <stdio.h>
    #include <kernel/dpl/TaskP.h>
    #include <kernel/dpl/ClockP.h>
    #include "enet_apputils.h"
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    #define SOCK_HOST_SERVER_IP6  ("FE80::12:34FF:FE56:78AB")
    
    #define SOCK_HOST_SERVER_PORT  (502)
    
    #define APP_SOCKET_MAX_RX_DATA_LEN (1024U)
    
    #define APP_SOCKET_NUM_ITERATIONS (1024U)
    
    #define MAX_IPV4_STRING_LEN (16U)
    
    static const uint8_t APP_CLIENT_TX_MSG1[] = "Greetings from Texas Instruments!";
    
    static const uint8_t APP_CLIENT_TX_MSG2[] = "This is a sample message";
    
    #if !LWIP_SOCKET
    #error "LWIP_SOCKET is not set! enable socket support in LwIP"
    #endif
    
    int netstate = 0;
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    struct App_hostInfo_t
    {
        struct sockaddr_in socketAddr;
    };
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    static void Appsocket_fillHostSocketInfo(struct App_hostInfo_t* pHostInfo);
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    static uint8_t gRxDataBuff[APP_SOCKET_MAX_RX_DATA_LEN];
    
    static struct App_hostInfo_t gHostInfo;
    
    static char   gHostServerIp4[MAX_IPV4_STRING_LEN] = "";
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    
    
    static void Appsocket_fillHostSocketInfo(struct App_hostInfo_t* pHostInfo)
    {
        ip_addr_t ipAddr;
        int32_t addr_ok;
        memset(&pHostInfo->socketAddr, 0, sizeof(pHostInfo->socketAddr));
    
        struct sockaddr_in*  pAddr = &pHostInfo->socketAddr;
        IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V4);
        addr_ok = ip4addr_aton(gHostServerIp4, ip_2_ip4(&ipAddr));
        pAddr->sin_len = sizeof(pHostInfo->socketAddr);
        pAddr->sin_family = AF_INET;
        pAddr->sin_port = PP_HTONS(SOCK_HOST_SERVER_PORT);
        inet_addr_from_ip4addr(&pAddr->sin_addr, ip_2_ip4(&ipAddr));
        EnetAppUtils_assert(addr_ok);
    
        return;
    }
    
    static void AppSocket_simpleClient(void* pArg)
    {
        static const uint8_t LOGIN_MSG[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x10, 0x14, 0x01, 0x00, 0x04, 0x08,       // login
                                              0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38};      // write 8888 8888, from address 5121
    
        static const uint8_t READ_COMM_TIMEOUT_MSG[] =  {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x14, 0x4e, 0x00, 0x01};   // read 5195, Com time out for M100
    
        static const uint8_t READ_UP_TIME_MSG[] =  {0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x15, 0x87, 0x00, 0x02};   // read 5511 up time for M100
    
        struct sockaddr* pAddr = pArg;
        int32_t sock = -1, ret = 0;
        struct timeval opt = {0}, tv = {0};
        fd_set readset = {0}, writeset = {0}, errset = {0};
    
        for (uint32_t i = 0; i < APP_SOCKET_NUM_ITERATIONS; i++)
        {
            //EnetAppUtils_print("<<< Iteration %d >>>> \r\n", i+1);
            EnetAppUtils_print(" Connecting to: %s:%d \r\n", gHostServerIp4, SOCK_HOST_SERVER_PORT);
            if (netstate == 0)
            {
                ClockP_usleep(4000000);
                continue;
            }
            /* create the socket */
            sock = lwip_socket(pAddr->sa_family, SOCK_STREAM, 0);
            if (sock < 0)
            {
                EnetAppUtils_print("ERR: unable to open socket\r\n");
                continue;
            }
    
            /* connect */
            ret = lwip_connect(sock, pAddr, pAddr->sa_len);
            if (ret != 0)
            {
                ret = lwip_close(sock);
                EnetAppUtils_print("ERR: unable to connect\r\n");
                continue;
            }
            EnetAppUtils_print("Connected to host\r\n");
    
            /* set recv timeout (100 ms) */
            opt.tv_sec = 0;
            opt.tv_usec = 100 * 1000;
            ret = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(opt));
            if (ret != 0)
            {
                ret = lwip_close(sock);
                EnetAppUtils_print("ERR: set sockopt failed\r\n");
                continue;
            }
    
            /*login rf modulator*/
            ret = lwip_write(sock, LOGIN_MSG, sizeof(LOGIN_MSG));
            if (ret != sizeof(LOGIN_MSG))
            {
                ret = lwip_close(sock);
                EnetAppUtils_print("ERR: socket write failed for login rf modulator.\r\n");
                continue;
            }
    
            ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
            if (ret <= 0)
            {
                 ret = lwip_close(sock);
                 EnetAppUtils_print("ERR: socket read failed for login rf modulator.\r\n");
                 continue;
            }
    
            for (uint32_t i=0; i<160; i++)
            {
                EnetAppUtils_print("Cycle number %d\r\n", i);
                ret = lwip_write(sock, READ_COMM_TIMEOUT_MSG, sizeof(READ_COMM_TIMEOUT_MSG));
                if (ret != sizeof(READ_COMM_TIMEOUT_MSG))
                {
                    ret = lwip_close(sock);
                    EnetAppUtils_print("ERR: READ_COMM_TIMEOUT_MSG failed\r\n");
                    continue;
                }
    
                ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
                if (ret <= 0)
                {
                     ret = lwip_close(sock);
                     EnetAppUtils_print("ERR: READ_COMM_TIMEOUT_MSG failed\r\n");
                     continue;
                }
    
                ret = lwip_write(sock, READ_UP_TIME_MSG, sizeof(READ_UP_TIME_MSG));
                if (ret != sizeof(READ_UP_TIME_MSG))
                {
                    ret = lwip_close(sock);
                    EnetAppUtils_print("ERR: READ_UP_TIME_MSG failed\r\n");
                    continue;
                }
    
                ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
                if (ret <= 0)
                {
                     ret = lwip_close(sock);
                     EnetAppUtils_print("ERR: READ_UP_TIME_MSG failed\r\n");
                     continue;
                }
    
                ClockP_usleep(100000);
            }
    #if 0
            /* Send data to Host */
            ret = lwip_write(sock, APP_CLIENT_TX_MSG1, sizeof(APP_CLIENT_TX_MSG1));
            if (ret != sizeof(APP_CLIENT_TX_MSG1))
            {
                ret = lwip_close(sock);
                EnetAppUtils_print("ERR: socket write failed\r\n");
                continue;
            }
            EnetAppUtils_print("Message to host: %s\r\n", APP_CLIENT_TX_MSG1);
    
            FD_ZERO(&readset);
            FD_ZERO(&writeset);
            FD_ZERO(&errset);
            FD_SET(sock, &readset);
            FD_SET(sock, &writeset);
            FD_SET(sock, &errset);
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            ret = lwip_select(sock + 1, &readset, &writeset, &errset, &tv);
            if (ret <= 0)
            {
                ret = lwip_close(sock);
                EnetAppUtils_print("ERR: socket select failed\r\n");
                continue;
            }
            EnetAppUtils_assert(!FD_ISSET(sock, &errset));
    
            if (FD_ISSET(sock, &readset))
            {
                ret = lwip_read(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN);
                if (ret <= 0)
                {
                     ret = lwip_close(sock);
                     EnetAppUtils_print("ERR: socket read failed\r\n");
                     continue;
                }
                gRxDataBuff[ret] = '\0';
                EnetAppUtils_print("Message from host: %s\r\n", gRxDataBuff);
            }
            if (FD_ISSET(sock, &writeset))
            {
                ret = lwip_write(sock, APP_CLIENT_TX_MSG2, sizeof(APP_CLIENT_TX_MSG2));
                if (ret != sizeof(APP_CLIENT_TX_MSG2))
                {
                     ret = lwip_close(sock);
                     EnetAppUtils_print("ERR: socket write failed!\r\n");
                     continue;
                }
                EnetAppUtils_assert(ret ==  sizeof(APP_CLIENT_TX_MSG2));
                EnetAppUtils_print("Message to host: %s\r\n", APP_CLIENT_TX_MSG2);
            }
    #endif
            /* close */
            ret = lwip_close(sock);
            EnetAppUtils_print("Closed Socket connection\r\n");
            ClockP_usleep(8000000);
        }
        return;
    }
    
    void AppSocket_showMenu(void)
    {
        ip_addr_t ipAddr;
        int32_t addr_ok = 0;
        EnetAppUtils_print(" UDP socket Menu: \r\n");
    
        do
        {
            //EnetAppUtils_print(" Enter server IPv4 address:(example: 192.168.101.100)\r\n");
            strcpy(gHostServerIp4, "192.168.0.100");
            //DebugP_scanf("%s", gHostServerIp4);
            addr_ok = ip4addr_aton(gHostServerIp4, ip_2_ip4(&ipAddr));
            EnetAppUtils_print("Server IPv4 address: %s\r\n", gHostServerIp4);
            TaskP_yield();
        } while (addr_ok != 1);
    }
    
    void AppSocket_startClient(void)
    {
        AppSocket_showMenu();
        Appsocket_fillHostSocketInfo(&gHostInfo);
        sys_thread_new("AppSocket_simpleClient", AppSocket_simpleClient, &gHostInfo.socketAddr, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
    }
    

    /*
     * 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_socket.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;
    
        Drivers_open();
        Board_driversOpen();
    
        DebugP_log("==========================\r\n");
        DebugP_log("  CPSW LWIP SIMPLE SOCKET \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);
        AppSocket_startClient();
    
        while (1)
        {
            ClockP_usleep(1000);
            App_printCpuLoad();
        }
    
        App_shutdownNetworkStack();
    
        EnetApp_driverDeInit();
        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);
    
        //IP4_ADDR(&ipaddr, 192,168,0,102);
        //IP4_ADDR(&netmask, 255,255,255,0);
    
        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]);
    }
    
    #define IP_ADDR_POOL_COUNT  (2U)
    
    const ip_addr_t gStaticIP[IP_ADDR_POOL_COUNT]   =  { IPADDR4_INIT_BYTES(192, 168, 0, 102) /* For NetifIdx = 0 */,  IPADDR4_INIT_BYTES(  10,  64,  1, 200) /* For NetifIdx = 1 */};
    
    const ip_addr_t gStaticIPGateway[IP_ADDR_POOL_COUNT] =  { IPADDR4_INIT_BYTES(192, 168, 0, 1) /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES(  10,   64, 1, 1) /* For NetifIdx = 1 */};
    
    const ip_addr_t gStaticIPNetmask[IP_ADDR_POOL_COUNT] =  { IPADDR4_INIT_BYTES(255,255,255,0)  /* For NetifIdx = 0 */, IPADDR4_INIT_BYTES(255,255,252,0) /* For NetifIdx = 1 */};
    
    
    static void App_allocateIPAddress()
    {
        sys_lock_tcpip_core();
    
        for (uint32_t  netifIdx = 0U; netifIdx < ENET_SYSCFG_NETIF_COUNT; netifIdx++)
        {
            netif_set_addr(g_pNetif[NETIF_INST_ID0 + netifIdx],
                                    &gStaticIP[NETIF_INST_ID0 + netifIdx],
                                    &gStaticIPNetmask[NETIF_INST_ID0 + netifIdx],
                                    &gStaticIPGateway[NETIF_INST_ID0 + netifIdx]);
        }
        sys_unlock_tcpip_core();
        return;
    }
    
    /*
    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))
        {
            netstate = 1;
            DebugP_log("Network Link UP Event\r\n");
        }
        else
        {
            netstate = 0;
            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;
    }
    

    After the connection is established, unplug the network cable and wait 8 seconds and then restore the connection, you can see the usage rate of MCU's CPU to rise sharply, from the original 3%+ to 20%+.

    if you have any question, you can contact me through email or teams, hongkai.xiao@elekta.com

  • After the connection is established, unplug the network cable and wait 8 seconds and then restore the connection, you can see the usage rate of MCU's CPU to rise sharply, from the original 3%+ to 20%+.

    I will look into this and get back to you.

    , you can contact me through email or teams, hongkai.xiao@elekta.com

    I would suggest you to connect to me thorugh TI-field team (FAE, you are in contact with).

    Regards

    Ashwani

  • Hi Ashwani,

    Can you reproduce it?

    Regards

  • Thanks for follow-up.

    ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk\examples\networking\lwip\enet_cpsw_socket,

    Any specific reason to use Industrial communication repo?

    Can you check and confirm you are seeing same issue with AM243x MCU+ SDK: Enet Lwip Socket Example ?

    C:\ti\mcu_plus_sdk_am243x_10_00_00_20\examples\networking\lwip\enet_lwip_cpsw

    Regards

    Ashwani

  • Hi Ashwani,

    We used ind_comms_sdk_am243x_09_02_00_08 SDK because we want to use beckhoff ethercat inside it.

    checked that mcu_plus_sdk_am243x_10_00_00_20\examples\networking\lwip\enet_cpsw_socket has no such issue.

    Thanks!

  • Are there any difference between mcu_plus_sdk_am243x_10_00_00_20 and ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk?

  • checked that mcu_plus_sdk_am243x_10_00_00_20\examples\networking\lwip\enet_cpsw_socket has no such issue.

    Thanks for confirmation.

    Are there any difference between mcu_plus_sdk_am243x_10_00_00_20 and ind_comms_sdk_am243x_09_02_00_08\mcu_plus_sdk?

    MCUSDK packed inside "ind_comms_sdk" is just to provide driver support for Industrial Communication examples.

    For Eethernet usage, I would suggest to use "mcu_plus_sdk_am243x_10_00_00_20".

    Regards

    Ashwani

  • Hi Ashwani,

    I found that there were manyTCP Dup ACK packets after unplugged the network cable and restored it, then reconnected. If I run a client on a Ubuntu machine that dose the same thing as MCU, there are only a few TCP Dup ACK packets that are disappeared very quickly.

  • Hi ,

    I found that there were manyTCP Dup ACK packets after unplugged the network cable and restored it, then reconnected. If I run a client on a Ubuntu machine that dose the same thing as MCU, there are only a few TCP Dup ACK packets that are disappeared very quickly.

    checked that mcu_plus_sdk_am243x_10_00_00_20\examples\networking\lwip\enet_cpsw_socket has no such issue.

    Can you help me to understand, Is this related to original question?

    Regards

    Ashwani

  • Hi Ashwani,

    Yes, it is related to original question. There are also manyTCP Dup ACK packets in original version. I suspect it is problem of Lwip TCP/IP stack. When the socket is disconnscted abnormally, the socket closure is not excuted correctly. TCP Dup ACK packets should be stoped, when it found that the previous connection has been closed.

  • Hi Hongkai,

    I followed steps https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/10_00_00_20/exports/docs/api_guide_am243x/EXAMPLES_ENET_LWIP_CPSW_SOCKET.html

    Then change code as you mentioned.

    I only changed app_socket.c and app_main.c. see below code.

    Then build and run.

    Setup:

    AM243x <=> D-link-Switch <=> Linux-PC

    I also removed and connect back LAN cable.

    Below are logs with no abnormal CPU load.

    ==========================
      CPSW LWIP SIMPLE SOCKET 
    ==========================
    Enabling clocks!
    EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:1 From 4 To 2 
    Mdio_open: MDIO Manual_Mode enabled
    Open MAC port 1
    EnetPhy_bindDriver: PHY 0: OUI:080028 Model:23 Ver:01 <-> 'dp83867' : OK
    Open MAC port 2
    EnetPhy_bindDriver: PHY 3: OUI:080028 Model:0f Ver:01 <-> 'dp83869' : OK
    PHY 0 is alive
    PHY 3 is alive
    Starting lwIP, local interface IP is dhcp-enabled
    [LWIPIF_LWIP] NETIF INIT SUCCESS
    Host MAC address-0 : 34:08:e1:80:d2:65
    Host MAC address-0 : 70:ff:76:1e:ee:37
    Enet IF UP Event. Local interface IP:0.0.0.0
    [LWIPIF_LWIP] Enet has been started successfully
    Enet IF UP Event. Local interface IP:192.168.0.102
    Waiting for network UP ...
    Waiting for network UP ...
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
    Network is UP ...
     UDP socket Menu: 
    Server IPv4 address: 192.168.0.100
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         10. 79s : CPU load =   3.92 %
     Connecting to: 192.168.0.100:502 
         15. 80s : CPU load =   3.71 %
     Connecting to: 192.168.0.100:502 
         20. 81s : CPU load =   3.84 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         25. 82s : CPU load =   3.49 %
     Connecting to: 192.168.0.100:502 
    Cpsw_handleLinkDown: Port 1: Link down
    MAC Port 1: link down
    Network Link DOWN Event
         30. 83s : CPU load =   3.84 %
     Connecting to: 192.168.0.100:502 
         35. 84s : CPU load =   3.75 %
     Connecting to: 192.168.0.100:502 
         40. 85s : CPU load =   3.49 %
     Connecting to: 192.168.0.100:502 
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
     Connecting to: 192.168.0.100:502 
         45. 86s : CPU load =   3.79 %
     Connecting to: 192.168.0.100:502 
         50. 87s : CPU load =   3.65 %
     Connecting to: 192.168.0.100:502 
         55. 88s : CPU load =   3.83 %
     Connecting to: 192.168.0.100:502 
    Cpsw_handleLinkDown: Port 1: Link down
    MAC Port 1: link down
    Network Link DOWN Event
         60. 89s : CPU load =   3.97 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         65. 90s : CPU load =   3.23 %
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
     Connecting to: 192.168.0.100:502 
         70. 91s : CPU load =   3.78 %
     Connecting to: 192.168.0.100:502 
         75. 92s : CPU load =   3.51 %
    �
    Starting NULL Bootloader ... 
    
    DMSC Firmware Version 10.0.8--v10.00.08 (Fiery Fox)
    DMSC Firmware revision 0xa
    DMSC ABI revision 4.0
    
    INFO: Bootloader_runCpu:180: CPU r5f1-0  is initialized to 800000000 Hz !!!
    INFO: Bootloader_runCpu:180: CPU r5f1-1 is initialized to 800000000 Hz !!!
    INFO: Bootloader_runCpu:180: CPU m4f0-0 is initialized to 400000000 Hz !!!
    INFO: Bootloader_loadSelfCpu:232: CPU r5f0-0 is initialized to 800000000 Hz !!!
    INFO: Bootloader_loadSelfCpu:232: CPU r5f0-1 is initialized to 800000000 Hz !!!
    INFO: Bootloader_runSelfCpu:242: All done, reseting self ...
    
    
    

    Regards

    Ashwani

  • Could you try it with app_socket.c I attached? I modified "static void AppSocket_simpleClient(void* pArg)" this function.

    Note: unplug the network cable and wait at lease 8 seconds.

  • Hi ,

    Here are files, I used on my side 

    main.c

    app_socket.c

    Note: unplug the network cable and wait at lease 8 seconds.

    Here is the logs with >8 sec wait after unplug cable.

    �
    Starting NULL Bootloader ... 
    
    DMSC Firmware Version 10.0.8--v10.00.08 (Fiery Fox)
    DMSC Firmware revision 0xa
    DMSC ABI revision 4.0
    
    INFO: Bootloader_runCpu:180: CPU r5f1-0  is initialized to 800000000 Hz !!!
    INFO: Bootloader_runCpu:180: CPU r5f1-1 is initialized to 800000000 Hz !!!
    INFO: Bootloader_runCpu:180: CPU m4f0-0 is initialized to 400000000 Hz !!!
    INFO: Bootloader_loadSelfCpu:232: CPU r5f0-0 is initialized to 800000000 Hz !!!
    INFO: Bootloader_loadSelfCpu:232: CPU r5f0-1 is initialized to 800000000 Hz !!!
    INFO: Bootloader_runSelfCpu:242: All done, reseting self ...
    
    ==========================
      CPSW LWIP SIMPLE SOCKET 
    ==========================
    Enabling clocks!
    EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:1 From 4 To 2 
    Mdio_open: MDIO Manual_Mode enabled
    Open MAC port 1
    EnetPhy_bindDriver: PHY 0: OUI:080028 Model:23 Ver:01 <-> 'dp83867' : OK
    Open MAC port 2
    EnetPhy_bindDriver: PHY 3: OUI:080028 Model:0f Ver:01 <-> 'dp83869' : OK
    PHY 0 is alive
    PHY 3 is alive
    Starting lwIP, local interface IP is dhcp-enabled
    [LWIPIF_LWIP] NETIF INIT SUCCESS
    Host MAC address-0 : 34:08:e1:80:d2:65
    Host MAC address-0 : 70:ff:76:1e:ee:37
    Enet IF UP Event. Local interface IP:0.0.0.0
    [LWIPIF_LWIP] Enet has been started successfully
    Enet IF UP Event. Local interface IP:192.168.0.102
    Waiting for network UP ...
    Waiting for network UP ...
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
    Network is UP ...
     UDP socket Menu: 
    Server IPv4 address: 192.168.0.100
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         10. 79s : CPU load =   3.87 %
     Connecting to: 192.168.0.100:502 
         15. 80s : CPU load =   3.54 %
     Connecting to: 192.168.0.100:502 
         20. 81s : CPU load =   4.09 %
     Connecting to: 192.168.0.100:502 
    Cpsw_handleLinkDown: Port 1: Link down
    MAC Port 1: link down
    Network Link DOWN Event
     Connecting to: 192.168.0.100:502 
         25. 82s : CPU load =   3.80 %
     Connecting to: 192.168.0.100:502 
         30. 83s : CPU load =   3.48 %
     Connecting to: 192.168.0.100:502 
         35. 84s : CPU load =   3.74 %
     Connecting to: 192.168.0.100:502 
         40. 85s : CPU load =   3.22 %
     Connecting to: 192.168.0.100:502 
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
     Connecting to: 192.168.0.100:502 
         45. 86s : CPU load =   3.87 %
     Connecting to: 192.168.0.100:502 
         50. 87s : CPU load =   3.70 %
     Connecting to: 192.168.0.100:502 
         55. 88s : CPU load =   4.08 %
     Connecting to: 192.168.0.100:502 
         60. 89s : CPU load =   3.98 %
    Cpsw_handleLinkDown: Port 1: Link down
    MAC Port 1: link down
    Network Link DOWN Event
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         65. 90s : CPU load =   3.62 %
     Connecting to: 192.168.0.100:502 
         70. 91s : CPU load =   3.75 %
     Connecting to: 192.168.0.100:502 
         75. 92s : CPU load =   3.22 %
     Connecting to: 192.168.0.100:502 
         80. 93s : CPU load =   3.75 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
         85. 94s : CPU load =   3.23 %
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
     Connecting to: 192.168.0.100:502 
         90. 95s : CPU load =   3.99 %
     Connecting to: 192.168.0.100:502 
         95. 96s : CPU load =   4.01 %
     Connecting to: 192.168.0.100:502 
        100. 97s : CPU load =   3.64 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        105. 98s : CPU load =   3.87 %
    Cpsw_handleLinkDown: Port 1: Link down
    MAC Port 1: link down
    Network Link DOWN Event
     Connecting to: 192.168.0.100:502 
        110. 99s : CPU load =   3.58 %
     Connecting to: 192.168.0.100:502 
        115.100s : CPU load =   3.75 %
     Connecting to: 192.168.0.100:502 
        120.101s : CPU load =   3.49 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        125.102s : CPU load =   3.49 %
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    Network Link UP Event
     Connecting to: 192.168.0.100:502 
        130.103s : CPU load =   4.00 %
     Connecting to: 192.168.0.100:502 
        135.104s : CPU load =   3.59 %
     Connecting to: 192.168.0.100:502 
        140.105s : CPU load =   3.79 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        145.106s : CPU load =   3.77 %
     Connecting to: 192.168.0.100:502 
        150.107s : CPU load =   3.46 %
     Connecting to: 192.168.0.100:502 
        155.108s : CPU load =   3.90 %
     Connecting to: 192.168.0.100:502 
        160.109s : CPU load =   3.56 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        165.110s : CPU load =   4.01 %
     Connecting to: 192.168.0.100:502 
        170.111s : CPU load =   3.66 %
     Connecting to: 192.168.0.100:502 
        175.112s : CPU load =   3.86 %
     Connecting to: 192.168.0.100:502 
        180.113s : CPU load =   3.79 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        185.114s : CPU load =   3.58 %
     Connecting to: 192.168.0.100:502 
        190.115s : CPU load =   3.82 %
     Connecting to: 192.168.0.100:502 
        195.116s : CPU load =   3.53 %
     Connecting to: 192.168.0.100:502 
        200.117s : CPU load =   3.88 %
     Connecting to: 192.168.0.100:502 
     Connecting to: 192.168.0.100:502 
        205.118s : CPU load =   3.92 %
     Connecting to: 192.168.0.100:502 
        210.119s : CPU load =   3.50 %
     Connecting to: 192.168.0.100:502 
        215.120s : CPU load =   3.85 %
     Connecting to: 192.168.0.100:502 
    
    

    The only difference, I see is I am working on MCU-SDK-10.00.

    Regards

    Ashwani

  • Thanks Ashwani! I also run a server("$ncat -e /bin/cat -kv -l 8888") on Ubuntu to test, the result is fine, but before the server run on a developping board,  the result was just as what I said before. Both reaults are normal if either client or server is running on PC(windows or linux), so I guess that it maybe a problem with the embeded TCP/IP stack.

  • it maybe a problem with the embeded TCP/IP stack.

    For that, you can connect with  LwIP (Light Weight IP stack) provider.

    Regards

    Ashwani