IP Pool Depletion

Hi All,

Original Post by me:

https://community.renesas.com/mcu-mpu/embedded-system-platform/f/forum/29322/ip-tasks-do-not-respond-after-an-arbitrary-period-of-time

Related threads viewed:

https://community.renesas.com/embedded-system-platform/synergy/f/forum/17295/ip-instance-stops-working-ssp-1-7-12

https://community.renesas.com/mcu-mpu/embedded-system-platform/f/forum/14492/netx-packet-pool-depletion/111974#111974

Platform:

Version: 2022-04 (22.4.0)
Build Id: R20220331-2313

SSP: v2.3.0

S7DK

Problem:

We are running MODBUS TCP Slave Server in a thread. The send and receive pool are different. After some time we find that the pool used for sending/replying is getting depleted.

Please feel free to ask for any relevant information. (Wireshark/source code etc.)

I have included the receive/send code with this post.

static BOOL _FnMODBUSTCPSlave(uint16_t u16NoMBSlaveClients, BOOL bMBSlaveFirst)
{
    BOOL bCmdBC = FALSE, bCmdValid = FALSE;
    ULONG ulactual_events = 0, ulMBSlaveMsg[2], utcp_bytes_received = 0, uStatus = 0;//,ulfree_packets=0;
    UINT uiStatus = 0, uiStatusRetrv = 0,uiStatusRetrvLenCheck=0; //,uiStatusReles = 0;
    uint16_t u16MsgTransLen = 0, u16RplyMsgsizeL = 0, u16SocketCheckCtr = 0,u16TCPSendError=DEF_TCP_SLAVE_REPLY_ERROR_NONE;
    NX_TCP_SOCKET *socket_ptr = NULL;
    NX_PACKET *pMB_RX_packet_ptr = NULL;
    NX_PACKET *pMB_TX_packet_ptr = NULL;
    uint16_t u16NoUsedSoc = 0;
    StructMBSlaveCmdExeParams *pMBSlaveCmdExeParams = &sMBSlaveTCPCmdExeParams;
    sMBSlaveTCPCmdExeParams.CmdOffset = 6;
    uint8_t *pMODBUSSlaveCmdRcv = sMBSlaveTCPCmdExeParams.MBReceiveFrame,u8PoolFreeCtr=0;
    uint8_t *pMBTranReplyFrame = sMBSlaveTCPCmdExeParams.MBReplyFrame;
    StructMBSlaveClientParam *pMBSlaveClientParam = NULL;

    //ssp_err_t g_MBSlave_ip_io_pool_err = SSP_SUCCESS;
    sMODBUSSlaveOpr.bMBSlaveSts = TRUE;
    sLogMODBUSComm.bMODBUSPoolDepleted=FALSE;
    sLogMODBUSComm.bIPPoolDepleted=FALSE;

    /* Start listening on the first available socket */
    FnSetMBSlaveStartSocketListen ();
    tx_timer_activate (&Timer_MBSlaveClientStatusCheck);

    while ((uiStatus = tx_event_flags_get (&EvDevInConfig, EV_FLAG_DEVICE_IN_CONFIG, TX_AND, &ulactual_events,
    TX_NO_WAIT)) == TX_NO_EVENTS)
    {
        uiStatus = tx_queue_receive (&QMBSlave, ulMBSlaveMsg, TX_NO_WAIT);
        if (TX_SUCCESS == uiStatus)
        {
            // MBSlave message received . process the same
            socket_ptr = (NX_TCP_SOCKET*) ulMBSlaveMsg[0];
            pMB_RX_packet_ptr = (NX_PACKET*) ulMBSlaveMsg[1];
            if (socket_ptr != NULL && pMB_RX_packet_ptr != NULL)
            {
                pMBSlaveClientParam = _FnMBSlaveFindClient (socket_ptr);
                if (pMBSlaveClientParam != NULL)
                {
                    utcp_bytes_received = 0;
                    //Check Rcv Msg Length
                    uiStatusRetrvLenCheck = nx_packet_length_get(pMB_RX_packet_ptr,&utcp_bytes_received);
                    if(uiStatusRetrvLenCheck==NX_SUCCESS && utcp_bytes_received<MAX_MODBUS_SLAVE_MESSAGE_RCV_LEN)
                    {
                        //Length is within limit
                        uiStatusRetrv = nx_packet_data_retrieve (pMB_RX_packet_ptr, pMODBUSSlaveCmdRcv,
                                                             &utcp_bytes_received);
                    }
                    else
                    {
                        //Cannot retrieve.
                        utcp_bytes_received=0;
                    }
                    nx_packet_release(pMB_RX_packet_ptr);
                    u16MsgTransLen = 0;
                    bCmdValid = FALSE;
                    //Get Client Socket Status.
                    nx_tcp_socket_info_get (&pMBSlaveClientParam->NX_TCPServerClientSocket, 0, 0, 0, 0, 0, 0, 0,
                                            &uStatus, 0, 0, 0);
                    if ((NX_TCP_ESTABLISHED == uStatus || NX_TCP_SYN_RECEIVED == uStatus)
                            && (uiStatusRetrv == TX_SUCCESS && utcp_bytes_received > 0))
                    {
                        tx_event_flags_set (&EvMBTCPSlaveClientConnected, pMBSlaveClientParam->EvMBSlaveClientConnected,
                        TX_OR);
                        //Command Recvd Process the same..
                        if (_FnMODBUSTCPSlaveValidateCmd (pMODBUSSlaveCmdRcv, utcp_bytes_received))
                        {
                            bCmdValid = TRUE;
                            pMBSlaveCmdExeParams->MBSlaveAddr = pMODBUSSlaveCmdRcv[6];  //MB Slave address
                            bCmdBC = FALSE;
                            if (pMBSlaveCmdExeParams->MBSlaveAddr == 0)
                            {
                                bCmdBC = TRUE;
                            }
                            pMBSlaveCmdExeParams->RcvMBSlaveCmd = pMODBUSSlaveCmdRcv[7];
                            //Reset MODBUSReplySend to FALSE
                            pMBSlaveCmdExeParams->bMODBUSReplySend = FALSE;
                            pMBSlaveCmdExeParams->bIllegalAddr = FALSE;
                            //Parse the message and get its response.
                            FnMBSlaveComdExe (pMBSlaveCmdExeParams, bCmdBC);
                            if (pMBSlaveCmdExeParams->bIllegalAddr == TRUE)
                            {
                                //Create message for illegal address.
                                FnMBSlaveExcepResp (DEF_MB_ILLEGAL_DATA_ADDRESS, pMBSlaveCmdExeParams);
                            }
                            if (pMBSlaveCmdExeParams->bMODBUSReplySend)
                            {
                                u16RplyMsgsizeL = pMBSlaveCmdExeParams->RplyMsgsize;
                                pMBTranReplyFrame[0] = pMODBUSSlaveCmdRcv[0]; //????  Cast using uchar or make both uint8_t
                                pMBTranReplyFrame[1] = pMODBUSSlaveCmdRcv[1];
                                pMBTranReplyFrame[2] = pMODBUSSlaveCmdRcv[2];
                                pMBTranReplyFrame[3] = pMODBUSSlaveCmdRcv[3];
                                pMBTranReplyFrame[4] = (uint8_t) ((u16RplyMsgsizeL) >> 8);
                                pMBTranReplyFrame[5] = (uint8_t) ((u16RplyMsgsizeL) & 0x00FF);

                                u16MsgTransLen = (uint16_t) (pMBSlaveCmdExeParams->RplyMsgsize + 6);
                                u8PoolFreeCtr=0;
                                do
                                {
                                    // Set Send Timeout Option  Place data in the packet.
                                    uiStatus = nx_packet_allocate (&g_MBSlave_ip_io_pool, &pMB_TX_packet_ptr,
                                    NX_TCP_PACKET,
                                                                   100);
                                    if(uiStatus == NX_SUCCESS)
                                    {
                                        break;
                                    }
                                    u8PoolFreeCtr++;
                                    tx_thread_sleep (100);
                                }
                                while (uiStatus != NX_SUCCESS && u8PoolFreeCtr < DEF_POOL_FREE_CHECK_COUNT_NO);
                                u16TCPSendError = 0;
                                if (uiStatus == NX_SUCCESS)
                                {
                                    sLogMODBUSComm.bMODBUSPoolDepleted=FALSE;

                                    uiStatus = nx_packet_data_append (pMB_TX_packet_ptr, pMBTranReplyFrame,
                                                                      (ULONG) (u16MsgTransLen), &g_MBSlave_ip_io_pool,
                                                                      NX_NO_WAIT);
                                    if (uiStatus == NX_SUCCESS)
                                    {
                                        uiStatus = nx_tcp_socket_send(socket_ptr, pMB_TX_packet_ptr, 100);
                                        if (uiStatus != NX_SUCCESS)
                                        {
                                            uiStatus = nx_packet_release(pMB_TX_packet_ptr);
                                            if (uiStatus != NX_SUCCESS)
                                            {
                                                u16TCPSendError = DEF_TCP_SLAVE_REPLY_ERROR_POOL_RELEASE_FAIL_SEND;
                                            }
                                            else
                                            {
                                                u16TCPSendError = DEF_TCP_SLAVE_REPLY_ERROR_SEND_FAIL;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        uiStatus = nx_packet_release(pMB_TX_packet_ptr);
                                        if (uiStatus != NX_SUCCESS)
                                        {
                                            u16TCPSendError = DEF_TCP_SLAVE_REPLY_ERROR_POOL_RELEASE_FAIL_APPEND;
                                        }
                                        else
                                        {
                                            u16TCPSendError = DEF_TCP_SLAVE_REPLY_ERROR_APPEND_FAIL;
                                        }
                                    }
                                }
                                else if(!sLogMODBUSComm.bMODBUSPoolDepleted)
                                {
                                   sLogMODBUSComm.bMODBUSPoolDepleted=TRUE;
                                   FnAddFaultLog (DEF_FAULT_MBSLAVE_TRANS_POOL_DEPLETE);
                                }

                            }

                        }

                        if (sLogMODBUSComm.bMODBUSTCPSlaveLog)
                        {
                            FnMODBUSCommMonLog (pMBSlaveClientParam->u16MBSlaveClientID, pMODBUSSlaveCmdRcv,
                                                utcp_bytes_received, pMBTranReplyFrame, u16MsgTransLen, bCmdValid,
                                                u16NoUsedSoc, u16TCPSendError, uiStatus,sLogMODBUSComm.bMODBUSPoolDepleted,en_COMM_OK_RESP_VALID);
                        }

                    }
                    else if (sLogMODBUSComm.bMODBUSTCPSlaveLog)
                    {
                        FnMODBUSCommMonLog (pMBSlaveClientParam->u16MBSlaveClientID, pMODBUSSlaveCmdRcv,
                                            utcp_bytes_received, pMBTranReplyFrame, 0, FALSE, u16NoUsedSoc,
                                            DEF_TCP_SLAVE_REPLY_ERROR_SOCKET_NOT_AVAILABLE,
                                            0,sLogMODBUSComm.bMODBUSPoolDepleted,en_COMM_FAIL);
                    }
                }
                else
                {
                    nx_packet_release(pMB_RX_packet_ptr);
                }
            }
            else if (pMB_RX_packet_ptr != NULL)
            {
                nx_packet_release(pMB_RX_packet_ptr);
            }
        }
        tx_thread_sleep (6);//(10);
        //Check Client Socket Status
        //Uncomment Later 29.06.2022
        u16SocketCheckCtr++;
        if (u16SocketCheckCtr >= DEF_SOCKET_MON_TIME_SEC)
        {
            u16SocketCheckCtr = 0;
            if ((tx_event_flags_get (&EvMBSlaveClientStatusCheck, EV_FLAG_TIMER_MBSLAVE_CLIENT_STATUS_CHECK,
            TX_AND_CLEAR,
                                     &ulactual_events,
                                     TX_NO_WAIT)) == TX_SUCCESS)
            {
                u16NoUsedSoc = FnMBSlaveTCPClientSocketStatusCheck (u16NoUsedSoc);
            }
        }
    }
    sMODBUSSlaveOpr.bMBSlaveSts = FALSE;
    tx_timer_deactivate (&Timer_MBSlaveClientStatusCheck);
    SSP_PARAMETER_NOT_USED(u16NoMBSlaveClients);
    bMBSlaveFirst = FALSE;
    return bMBSlaveFirst;
}

I need a solution ASAP,

Thanks for your help in advance.

Regards,

Surojit