硬汉嵌入式论坛

 找回密码
 立即注册
查看: 619|回复: 2
收起左侧

[LwIP] 使用RTOS进行UDP通信,但是有时却接收不到信息

[复制链接]

4

主题

5

回帖

17

积分

新手上路

积分
17
发表于 2023-11-6 13:14:52 | 显示全部楼层 |阅读模式
大佬们好,最近在使用RTOS进行一个UDP+串口的一个项目,在到UDP通信时出现了些问题,
在上位机使用野火串口助手发送一个614字节的数据时,在keil5的调试功能中查看是否接收到了数据,发现有时可以接收到,但是经常会发送过来但是我的缓存器却没有数据。

使用wireshark进行数据抓包时能够抓到发送的数据,但是在buff中却是接收不成功。有时新的数据在野火串口助手中提示发送成功,但是我的缓存器却没有更新。图片中是我的代码。‘


这是我的UDP协议的接收和发送代码。

void udp_recv_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    if (p != NULL)
    {
        /* 获取接收到的数据的长庿 */
        int receivedDataLength = p->len;
        
        /* 确保接收到的数据不超过缓冲区的剩余空闿 */
        if (streamBufferIndex + receivedDataLength <= STREAM_BUFFER_SIZE)
        {
            /* 将接收到的数据复制到StreamBuffer丿 */
            memcpy(&StreamBuffer[streamBufferIndex], p->payload, receivedDataLength);
            
            /* 更新缓冲区索弿 */
            streamBufferIndex += receivedDataLength;
        }
        else
        {
          streamBufferIndex = 0;  
                                        // 缓冲区空间不足以容纳接收到的数据,需要处理溢出情冿
        }

        /* 发&#40897;回应数据(如果霿要的话) */
        udp_sendto(upcb, p, addr, port);

        /* 释放接收缓冲匿 */
        pbuf_free(p);
    }
}
void udp_server_init(void)
{
        struct udp_pcb *upcb;

        /* 创建丿个UDP套接孿 */
        upcb = udp_new();
        if (upcb != NULL)
        {
                        /* 绑定IP地址和端口号 */
                        ip_addr_t ipaddr;
                        IP_ADDR4(&ipaddr, 192,168,1,53); // 本地IP地址
                        udp_bind(upcb, &ipaddr, 9999);

                        /* 设置接收回调函数 */
                        udp_recv(upcb, udp_recv_callback, NULL);
        }
}

void udp_send_data(const uint8_t *TxBuff, uint16_t data_length)
{
    struct udp_pcb *send_pcb;
    err_t result;

    // 创建UDP发&#40897;套接字
    send_pcb = udp_new();

    if (send_pcb != NULL)
    {
        ip_addr_t target_ip;
        IP4_ADDR(&target_ip, 192, 168, 1, 158); // 设置目标IP地址

        // 设置目标端口叿
        uint16_t target_port = 10000;

        // 创建丿个pbuf来保存数捿
        struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, data_length, PBUF_RAM);

        if (p != NULL)
        {
            // 将数据复制到pbuf
            pbuf_take(p, TxBuff, data_length);

            // 发&#40897;数捿
            result = udp_sendto(send_pcb, p, &target_ip, target_port);

            // 释放pbuf
            pbuf_free(p);
        }
        else
        {
            // 处理内存分配错误
        }

        // 释放UDP套接孿
        udp_remove(send_pcb);
    }
    else
    {
        // 处理UDP套接字创建错诿
    }
}


这是我的RTOS任务创建函数




osThreadId EthTaskHandle;
osThreadId UartTaskHandle;
osThreadId IMU_TaskHandle;
osThreadId YaoKongQiHandle;
osThreadId back_motorHandle;

void StartEthTask(void const * argument);
void StartUartTask(void const * argument);
void IMU_TASK(void const * argument);
void YKQ_Task(void const * argument);
void Back_Motor(void const * argument);

extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

/* 二忼信叿 */
SemaphoreHandle_t U2Semaphore;

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
void MX_FREERTOS_Init(void) {
  osThreadDef(EthTask, StartEthTask, osPriorityHigh, 0, 1024);
  EthTaskHandle = osThreadCreate(osThread(EthTask), NULL);

  osThreadDef(UartTask, StartUartTask, osPriorityNormal, 0, 128);
  UartTaskHandle = osThreadCreate(osThread(UartTask), NULL);

  osThreadDef(IMU_Task, IMU_TASK, osPriorityAboveNormal, 0, 128);
  IMU_TaskHandle = osThreadCreate(osThread(IMU_Task), NULL);

  osThreadDef(YaoKongQi, YKQ_Task, osPriorityAboveNormal, 0, 128);
  YaoKongQiHandle = osThreadCreate(osThread(YaoKongQi), NULL);

  osThreadDef(back_motor, Back_Motor, osPriorityAboveNormal, 0, 256);
  back_motorHandle = osThreadCreate(osThread(back_motor), NULL);


}



下边是我的各种任务创建


void StartEthTask(void const * argument)
{
  MX_LWIP_Init();
  for(;;)
  {       
                udp_server_init();
          processControlData(StreamBuffer);
                ConvertHexArrayToFloatArray(controlDataArray, q_data,dq_data, 20);
          processDataAndStore(kd_buff, controlDataArray, 20);
    processDataTau(tau_buff,controlDataArray,20);
          processDataKp(kp_buff, controlDataArray, 20);
          
    osDelay(20);
  }
}

void StartUartTask(void const * argument)
{
        cmd.id=1;                         //????????????
        cmd.mode=1;
        cmd.T=0.1;
        cmd.W=0;
        cmd.Pos=0;
        cmd.K_P=0;
        cmd.K_W=0;
                     
  for(;;)
  {
                HAL_UART_Transmit(&huart2,Rx,sizeof(Rx),100);

                SERVO_Send_recv(&cmd, &data);
                osDelay(100);
  }
}

void IMU_TASK(void const * argument)
{
  /* USER CODE BEGIN IMU_TASK */

       
  /* Infinite loop */
  for(;;)
  {
                IMUData imu_data;
               
                HAL_UART_Receive_IT(&huart5,IMU_Rx,sizeof(IMU_Rx));
                parseAndStoreIMUData(IMU_Rx, &imu_data);

                osDelay(100);
  }
}

void YKQ_Task(void const * argument)
{
  for(;;)
  {
               
                HAL_UART_RxCpltCallback(&huart4);
                SBUS_Reveive();
                SBUS_Handle();
    osDelay(10);
  }
  /* USER CODE END YKQ_Task */
}

void Back_Motor(void const * argument)
{
  /* USER CODE BEGIN Back_Motor */
//MI_motor_init(&MI_Motor,&hcan1);//主要是初始化can,也可以加自己的初始化代砿
//MI_motor_enable(&MI_Motor,0x7F);
  /* Infinite loop */
  for(;;)
  {
//          MI_motor_controlmode(&MI_Motor, 0.1, 0 , 0, 0, 0);

    osDelay(1);
  }
  /* USER CODE END Back_Motor */
}



一共是五个任务函数,开始我以为可能是UDP的优先级不够,发现调高后仍然是同样的情况,后来将其他任务全部注释,运行后同样问题。
感谢各位大佬指点。






11.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2023-11-7 10:58:36 | 显示全部楼层
UDP发送后,保证上一次收到后,再发第2次。否则容易丢包。
回复

使用道具 举报

4

主题

5

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-10 10:01:35 | 显示全部楼层
感谢您的回复
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 05:23 , Processed in 0.164850 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表