问题起因:
使用lwip-2.0.3版本,启用DHCP,经常出现DHCP未分配的问题(使用命令ifconfig,查看flags,有UP LINK_UP,没有ip gw dns等地址),一步步查看底层,发现在drv_eth.c文件中的eth发送接口rt_stm32_eth_tx中,DmaTxDesc的OWN位始终没有自动清除,见下图红框处:
查看寄存器,对比正常使用的情况下,发现出现异常时DMAOMR->FTF位始终是置位的,该位说明见下图:
进一步查看置位这步的操作,发现是在启动ETH时配置,调用关系如下图:
在HAL驱动置位FTF时,注释说明是要等待一段时间,但是代码的实现,在写入DMAOMR寄存器后,立即用tmpreg1缓存读取DMAOMR寄存器的值,这时可能出现问题,tmpreg1缓存的值可能是已清除FTF位的值,也有可能是未清除FTF位的值,所以在最后写入的时候导致再次置位了DMAOMR->FTF.按手册的说法,在改位清除前不能对DMAOMR寄存器执行写操作,但是在HAL_ETH_Start函数中,紧跟ETH_FlushTransmitFIFO操作后的ETH_DMATransmissionEnable操作就有对DMAOMR->ST的写入操作,而且从此开始DMAOMR->FTF位一直未能自动清除,导致ETH的发送描述符在第一次发送后被DMA占用,但是一直不能释放给CPU,从而导致后续的所有发送都会失败。
这些是我看到的现象,我将ETH_FlushTransmitFIFO中最后一次的赋值注释后,再没出现发送异常的问题,但是对这个HAL库的写法不太明白,为什么这么设计,为什么又会出现FIFO未清除会导致DMA描述符的OWN不能自动释放的问题,我的改动目前测试暂时没有发现问题,后续会继续测试(未出现可能是时间比较短,会保持长时间重复重启测试)。请教各位有没有更清楚的说法?