解决STM32以太网程序烧录GD32芯片时偶尔出现的网卡添加失败问题

项目场景:

GD32F407使用以太网口连接的方式,作为服务器连接多个客户端,网络采用四层结构,实现方式为Lan8720+LwIP+Freertos。


问题描述

博主由于比较懒,所以直接使用CubeMX生成的STM32的程序烧录GD32同款芯片中,出现了以太网添加网络失败的bug,这个bug是偶发的,有时候一天一次都不会出现,有时候会连续出现,debug后程序卡在如下程序段中:

netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);

原因分析:

这里软件原因就很复杂了,有可能是phy芯片初始化失败,也有可能是网络添加过程中被其他任务抢断,也有可能是两款MCU的ETH_IO速率不兼容,也有可能是其他不兼容。

这里经过一系列的排查最终锁定在了速率不兼容上,但是不是ETH_IO的不兼容,是整个芯片的晶振速率,以及总线上速率的不一致;

参考:


解决方案:

你需要去STM32的Driver文件里找到函数:

static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)//修改前
{
  __IO uint32_t tmpreg = 0;

  /* Set the Flush Transmit FIFO bit */
  (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;

  /* Wait until the write operation will be taken into account:
     at least four TX_CLK/RX_CLK clock cycles */
   tmpreg = (heth->Instance)->DMAOMR;
  HAL_Delay(ETH_REG_WRITE_DELAY);//stm32的这个延时不够
   (heth->Instance)->DMAOMR = tmpreg;
}

由于GD32移植了STM32程序,在相同的168Mhz主频下相同总线时钟分配,HAL_Delay(ETH_REG_WRITE_DELAY);这个延时不足以清除fifo标志位,要改为:

static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)//修改后
{
  __IO uint32_t tmpreg = 0;

  /* Set the Flush Transmit FIFO bit */
  (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;

  /* Wait until the write operation will be taken into account:
     at least four TX_CLK/RX_CLK clock cycles */
//  tmpreg = (heth->Instance)->DMAOMR;
//  HAL_Delay(ETH_REG_WRITE_DELAY);//stm32的这个延时不够
//  (heth->Instance)->DMAOMR = tmpreg;
    while((ETH->DMAOMR & ETH_DMAOMR_FTF) != 0);
    for(uint32_t i=0;i<0xffff;i++);
}

作者:大能人BigMan

物联沃分享整理
物联沃-IOTWORD物联网 » 解决STM32以太网程序烧录GD32芯片时偶尔出现的网卡添加失败问题

发表回复