hz110 发表于 2023-11-6 13:14:52

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

大佬们好,最近在使用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, p->payload, receivedDataLength);
            
            /* 更新缓冲区索弿 */
            streamBufferIndex += receivedDataLength;
      }
      else
      {
          streamBufferIndex = 0;
                                        // 缓冲区空间不足以容纳接收到的数据,需要处理溢出情冿
      }

      /* 发鿁回应数据(如果霿要的话) */
      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发鿁套接字
    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);

            // 发鿁数捿
            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;

/* 二忼信叿 */
SemaphoreHandle_t U2Semaphore;

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
*ppxIdleTaskStackBuffer = &xIdleStack;
*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的优先级不够,发现调高后仍然是同样的情况,后来将其他任务全部注释,运行后同样问题。
感谢各位大佬指点。






eric2013 发表于 2023-11-7 10:58:36

UDP发送后,保证上一次收到后,再发第2次。否则容易丢包。

hz110 发表于 2023-11-10 10:01:35

感谢您的回复
页: [1]
查看完整版本: 使用RTOS进行UDP通信,但是有时却接收不到信息