解决STM32以太网程序烧录GD32芯片时偶尔出现的网卡添加失败问题
项目场景:
GD32F407使用以太网口连接的方式,作为服务器连接多个客户端,网络采用四层结构,实现方式为Lan8720+LwIP+Freertos。
问题描述
博主由于比较懒,所以直接使用CubeMX生成的STM32的程序烧录GD32同款芯片中,出现了以太网添加网络失败的bug,这个bug是偶发的,有时候一天一次都不会出现,有时候会连续出现,debug后程序卡在如下程序段中:
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_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