如何使用 LWIP、UDP

问题描述

我正在尝试使用 STM32H745 和 UDP 通过以太网向我的计算机和 LwIP 发送数据。我已经成功配置了卡,现在我可以将数据从卡发送到计算机上运行的 Python 脚本。但是,我不明白 udp_recv 是如何工作的 <udp,lwip> 或如何在 LwIP 上使用 UDP 接收数据,我找不到这样做的例子。在哪里接收数据?我应该使用 udp_recv 吗?

在主循环中,我运行 MX_LWIP_Process,它运行 ethernetif_input,以某种方式处理接收到的数据,但我不明白它把它放在哪里。

以下是主要代码,仅供参考。

const char* message = "a";

HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_1); // orange

ip_addr_t PC_IPADDR;
IP_ADDR4(&PC_IPADDR,192,168,1,200);

u16_t port = 8000;

struct udp_pcb* my_udp = udp_new();

struct pbuf* udp_buffer = NULL;

/* Infinite loop */
for (;; )
{
    MX_LWIP_Process();
    HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_1); // orange
    HAL_Delay(1000);

    udp_buffer = pbuf_alloc(PBUF_TRANSPORT,strlen(message),PBUF_RAM);
    if (udp_buffer != NULL)
    {
        memcpy(udp_buffer->payload,message,strlen(message));
        udp_sendto(my_udp,udp_buffer,&PC_IPADDR,port);
        pbuf_free(udp_buffer);
    }

    //udp_recv (struct udp_pcb *pcb,udp_recv_fn recv,void *recv_arg)
}

解决方法

udp_recv() 实际上并不接收 UDP 数据报(尽管有它的名字)。它注册一个回调函数,当数据报被缓冲时,该回调函数将被 MX_LWIP_Process() 调用。最好将其称为 udp_set_recv_callback(),但事实就是如此。

为此,您应该在执行循环之前调用一次:

    udp_bind( my_udp,IP_ADDR_ANY,port ) ;
    udp_recv( my_udp,udp_receive_callback,NULL ) ;

    /* Infinite loop */
    for (;; )
    {
         // Run the CubeMX LwIP stack
         MX_LWIP_Process() ;

         ...
    }

其中 udp_receive_callback 是将在收到数据报时调用的函数:

void udp_receive_callback( void* arg,// User argument - udp_recv `arg` parameter
                           struct udp_pcb* upcb,// Receiving Protocol Control Block
                           struct pbuf* p,// Pointer to Datagram
                           const ip_addr_t* addr,// Address of sender
                           u16_t port )            // Sender port 
{

  // Process datagram here (non-blocking code)
  ...
  
  // Must free receive pbuf before return
  pbuf_free(p);
}

示例包括:

文档可以在 https://www.nongnu.org/lwip/2_0_x/group__udp__raw.html

找到