You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32中UDP接收回调函数udpcall未执行的原因排查

STM32 UDP回调未触发问题排查与修复

核心问题1:UDP控制块作用域错误

main函数中struct udp_pcb* Demo_upcb是局部变量,出初始化代码块后会被销毁,定时器回调中使用的Demo_upcb是未初始化的野指针,导致udp_recv绑定完全无效。
修复方案:将Demo_upcb声明为全局变量,在main中完成初始化:

// 在文件顶部(main函数外)声明全局变量
struct udp_pcb* Demo_upcb = NULL;

int main(void)
{
    // ... 系统初始化代码 ...
    /* USER CODE BEGIN 2 */
    ip_addr_t myIPADDR,destip;
    IP_ADDR4(&myIPADDR,192,168,33,1);
    IP_ADDR4(&destip,192,168,33,101);

    Demo_upcb = udp_new();
    // ... 后续绑定代码 ...
}

核心问题2:重复绑定UDP回调

定时器每秒调用udp_recv属于冗余操作,udp_recv仅需调用一次即可完成回调绑定,重复绑定无意义且可能引发未知问题。
修复方案:将udp_recv移至main初始化流程中,放在udp_bind成功之后:

int main(void)
{
    // ... 系统初始化代码 ...
    err_t er3 = udp_bind(Demo_upcb, &myIPADDR, 8);
    if(er3 != ERR_OK)
    {
        while(1)
        {
            HAL_Delay(200);
            HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
        }
    }
    // 仅需一次绑定UDP接收回调
    udp_recv(Demo_upcb, &udpcall, NULL);
    // ... 其他初始化代码 ...
    HAL_TIM_Base_Start_IT(&htim6);
}

同时删除定时器回调中的udp_recv调用,增加定时器实例判断避免影响其他定时器:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)
    {
        HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);//Blue LED
    }
}

潜在问题3:UDP绑定的IP地址限制

当前代码绑定固定IP192.168.33.1,若STM32实际IP并非此地址(比如使用DHCP自动获取),将无法接收数据包。建议绑定任意IP适配所有场景:

// 替换固定IP绑定为任意IP
err_t er3 = udp_bind(Demo_upcb, IP_ADDR_ANY, 8);

潜在问题4:UDP回复的冗余操作

UDP是无连接协议,udp_connect仅记录目标地址端口,并非必须操作,可直接用udp_sendto发送回复:

void udpcall(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    sprintf(buffer,"This is UDP message \r\n");
    struct pbuf* psend = pbuf_alloc(PBUF_TRANSPORT, strlen(buffer), PBUF_RAM);
    if(psend != NULL) // 增加内存分配失败判断
    {
        memcpy(psend->payload, buffer , strlen(buffer));
        // 直接用udp_sendto发送,无需提前连接
        err_t err2 = udp_sendto(pcb, psend, addr, port);
        if(err2 == ERR_OK)
        {
            HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);//Green LED
        }
        pbuf_free(psend);
    }
    pbuf_free(p);
}

额外检查项

  • 确认STM32的IP地址、UDP端口(8)与发送工具的目标配置完全一致
  • 检查LWIP配置中LWIP_UDP宏是否被定义为1(开启UDP功能)
  • 确认以太网物理连接正常,网线、交换机/路由器工作正常
  • 排查笔记本和STM32之间的防火墙设置,确保UDP端口未被拦截

内容的提问来源于stack exchange,提问作者confusedfresher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 13:03:32