RTOS built packet lost detection program leads to loss packet on my board

I built a program on my TI board in order to detect packet lost on connected lidar with UDP. But I found that the board itself would make lost packet behaviors which for comparison I got no lost packets on PC site on the same lidar. The program below created a socket to receive packets transported form the lidar and decode such for bytes as udp sequence as a comparison with the last one in order to detect if there is a loss packet at this moment. I highly doubt there is any system-level thing would block at some time, maybe to clean the buffer or anything else so that at that period of time, packet receiving would stop. PLZ help me with this, I have stuck on this for some time

/* ========================================================================== */
/*                             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_PORT  (2368)

#define APP_SOCKET_MAX_RX_DATA_LEN (16384U)

#define APP_SOCKET_NUM_ITERATIONS (1000U)

#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



/* ========================================================================== */
/*                         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;
    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)
{
    for (uint32_t j = 100; j > 0; j--)
    {
        struct sockaddr* pAddr = pArg;
        struct sockaddr_in remote_addr;
        socklen_t addr_len = sizeof(remote_addr);
        int32_t sock = -1, ret = 0, ret_timeout = 0, ret1 = 0;
        struct timeval tv = {0};
        fd_set readset = {0};
    //    EnetAppUtils_print("Connecting to: %s:%d \r\n", gHostServerIp4, SOCK_HOST_SERVER_PORT);

        /* 创建套接字 */
        sock = lwip_socket(AF_INET, SOCK_DGRAM, 0);
        if (sock < 0)
        {
            EnetAppUtils_print("ERR: unable to open socket\r\n");
            return;
        }

        /* 绑定到端口 2368 以接收 UDP 数据包 */
        struct sockaddr_in local_addr;
        memset(&local_addr, 0, sizeof(local_addr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_port = htons(SOCK_HOST_SERVER_PORT);
        local_addr.sin_addr.s_addr = INADDR_ANY;

        if (lwip_bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0)
        {
            EnetAppUtils_print("ERR: unable to bind to port 2368\r\n");
            lwip_close(sock);
            return;
        }

    //    EnetAppUtils_print("Socket bound to port 2368, waiting for UDP packets...\r\n");

        /* 设置接收缓冲区大小 */
        int recv_buffer_size = 8388608; // 64KB 缓冲区大小
        int actual_recv_buffer_size = 0;
        ret = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recv_buffer_size, sizeof(recv_buffer_size));
        if (ret != 0)
        {
            lwip_close(sock);
            EnetAppUtils_print("ERR: set receive buffer size failed\r\n");
            return;
        }

        /* 设置接收超时时间 */
        struct timeval recv_timeout;
        recv_timeout.tv_sec = 1;
        recv_timeout.tv_usec = 0;
        ret_timeout = lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
    //    socklen_t optlen = sizeof(actual_recv_buffer_size);  // 告诉 lwip_getsockopt 这个变量的大小
    //
    //    ret1 = lwip_getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &actual_recv_buffer_size, &optlen);
    //    if (ret1 == 0)
    //    {
    //        // 打印实际的接收缓冲区大小
    //        EnetAppUtils_print("Receive buffer size set to: %d bytes\r\n", actual_recv_buffer_size);
    //    }
    //    else
    //    {
    //        EnetAppUtils_print("ERR: unable to get receive buffer size\r\n");
    //    }
    //
    //    if (ret1 != 0)
    //    {
    //        lwip_close(sock);
    //        EnetAppUtils_print("ERR: set receive timeout failed\r\n");
    //        return;
    //    }

        uint32_t udpsequence_last = 0xFFFFFFFF; // 未初始化的标志值
        uint32_t udpsequence_now = 0;
        uint32_t LOSS_PKT_TOTAL = 0; // 累计丢失的包数
        uint32_t TOTAL_PACKETS_EXPECTED = 0; // 期望的总包数
        uint32_t round = 0;

        for (uint32_t i = 0; i < APP_SOCKET_NUM_ITERATIONS; i++)
        {
            /* 准备 fd_set */
            FD_ZERO(&readset);
            FD_SET(sock, &readset);

            tv.tv_sec = 1;
            tv.tv_usec = 0; // 1秒超时
            ret = lwip_select(sock + 1, &readset, NULL, NULL, &tv);

            if (ret <= 0)
            {
                if (ret == 0)
                {
                    // 超时,无数据到达,继续等待
                    continue;
                }
                else
                {
                    int err = errno;
                    const char *err_str = strerror(err);
                    EnetAppUtils_print("Socket select error: %s (errno = %d)\r\n", err_str, err);
                    continue;
                }
            }

            if (FD_ISSET(sock, &readset))
            {
                /* 接收数据 */
                ret = lwip_recvfrom(sock, gRxDataBuff, APP_SOCKET_MAX_RX_DATA_LEN, 0,
                                    (struct sockaddr*)&remote_addr, &addr_len);
                if (ret < 0)
                {
                    int err = errno;
                    EnetAppUtils_print("ERR: socket recvfrom failed: %s (errno = %d)\r\n", strerror(err), err);
                    continue;
                }

                /* 检查缓冲区是否已满 */
               if (ret == APP_SOCKET_MAX_RX_DATA_LEN)
               {
                   /* 如果缓冲区满了,打印信息 */
                   EnetAppUtils_print("Buffer full! Received exactly %u bytes.\r\n", APP_SOCKET_MAX_RX_DATA_LEN);
                   return;
               }

                /* 解析 UDP 序列号(假设它位于数据的已知偏移处) */
                if (ret >= 36) // 确保数据长度足够
                {
                    // 提取缓冲区中的 4 字节序列号
                    udpsequence_now = (uint32_t)((gRxDataBuff[ret - 4]) |
                                                 (gRxDataBuff[ret - 3] << 8) |
                                                 (gRxDataBuff[ret - 2] << 16) |
                                                 (gRxDataBuff[ret - 1] << 24));

                    if (udpsequence_last == 0xFFFFFFFF)
                    {
                        // 首次接收数据,初始化 udpsequence_last
                        udpsequence_last = udpsequence_now;
                        TOTAL_PACKETS_EXPECTED = 1;
                        round +=1;
                    }
                    else
                    {
                        uint32_t expected_seq = udpsequence_last + 1;
                        uint32_t jump_value = 0;

                        if (udpsequence_now > expected_seq)
                        {
                            EnetAppUtils_print("LOST AND FOUND NOW: %u\r\n", udpsequence_now);
                            EnetAppUtils_print("LOST AND FOUND SHOULD: %u\r\n", expected_seq);
                            EnetAppUtils_print("LOST AND FOUND ROUND: %u\r\n", round);
                            jump_value = udpsequence_now - expected_seq;
                            return;

                        }
                        else
                        {
                            // 序列号溢出处理(假设序列号为 32 位无符号整数)
    //                        jump_value = (UINT32_MAX - expected_seq) + udpsequence_now + 1;
                            round += 1;
                            jump_value = 0;
                        }

                        // 累加丢失的包数量
                        LOSS_PKT_TOTAL += jump_value;
                        jump_value = 0;

                        // 更新期望的总包数
                        TOTAL_PACKETS_EXPECTED += (jump_value + 1);

                        // 更新 udpsequence_last
                        udpsequence_last = udpsequence_now;
                    }
                }
                else
                {
                    EnetAppUtils_print("ERR: received data too short for sequence number\r\n");
                }
            }
        }

        /* 计算并打印总丢包率 */
        lwip_close(sock);
    //    float lost_rate = 0.0f;
    //    if (TOTAL_PACKETS_EXPECTED > 0)
    //    {
    //        lost_rate = ((float)LOSS_PKT_TOTAL / (float)TOTAL_PACKETS_EXPECTED) * 100.0f;
    //    }
        EnetAppUtils_print("Total lost packeges: %u\r\n", LOSS_PKT_TOTAL);
        EnetAppUtils_print("sock check: %u\r\n", sock);
    //    EnetAppUtils_print("Total expected packeges: %u\r\n", APP_SOCKET_NUM_ITERATIONS);
    //    EnetAppUtils_print("Total lost rate: %.2f%%\r\n", lost_rate);

        /* 关闭套接字 */

    //    EnetAppUtils_print("Closed Socket connection\r\n");
        ClockP_sleep(1);
    };
    return;
}



void AppSocket_showMenu(void)
{
    ip_addr_t ipAddr;
    int32_t addr_ok = 0;
    EnetAppUtils_print("UDP socket Menu: \r\n");

    /* 写死IP地址为192.168.1.201 */
    strcpy(gHostServerIp4, "192.168.1.201");
//    EnetAppUtils_print("Using fixed server IP: %s\r\n", gHostServerIp4);

    /* 检查IP地址格式是否正确 */
    addr_ok = ip4addr_aton(gHostServerIp4, ip_2_ip4(&ipAddr));
    EnetAppUtils_assert(addr_ok == 1);
    TaskP_yield();
}

void AppSocket_startClient(void)
{
    AppSocket_showMenu();
    Appsocket_fillHostSocketInfo(&gHostInfo);
    sys_thread_new("AppSocket_simpleClient", AppSocket_simpleClient, &gHostInfo.socketAddr, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
}

Hi @derrick,
I haven’t been able to identify any specific issues. However, I’d like to suggest a potential explanation for the situation you’re experiencing.

In UDP communications, it’s important to note that packets can sometimes arrive out of sequence. For instance, a packet with sequence number 2 might arrive before a packet with sequence number 1. This is a normal characteristic of UDP transmission.

Given this behavior, I’m wondering if this out-of-sequence arrival might be affecting the calculation of lost packets in your system. It’s possible that packets arriving out of order are being misinterpreted as lost, leading to inaccurate calculations.

Thank you.

Are you saying that you observe packet loss when you receive UDP data on the board and do not observe any loss when you receive the same UDP data on PC? If yes, note that data loss in UDP is normal and expected. You can try to capture network trace and enable LWIP debug logs to point down the cause of the loss. In either case, your application need to be resilient to packet loss if you are using UDP.