[STM32H7] STM32H7RS LWIP + FreeRTOS SWR 位无法清零

[复制链接]
144|13
万法归宗 发表于 2026-10-19 08:53 | 显示全部楼层 |阅读模式
我使用 Nucleo-H7S3L8 开发板,这两天一直被HAL_ERROR折磨。 SWR 位正常情况下软件复位成功后,该位会自动清除;但执行软件复位之后,这个 SWR 位始终无法自行清零。
具体现象:
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{
uint32_t tickstart;

if (heth == NULL)
{
return HAL_ERROR;
}
if (heth->gState == HAL_ETH_STATE_RESET)
{
heth->gState = HAL_ETH_STATE_BUSY;

#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)

ETH_InitCallbacksToDefault(heth);

if (heth->MspInitCallback == NULL)
{
heth->MspInitCallback = HAL_ETH_MspInit;
}

/* Init the low level hardware */
heth->MspInitCallback(heth);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC. */
HAL_ETH_MspInit(heth);

#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
}

__HAL_RCC_SBS_CLK_ENABLE();

if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
{
HAL_SBS_ConfigEthernetPHY(SBS_ETHERNET_PHY_GMII_OR_MII);
}
else
{
HAL_SBS_ConfigEthernetPHY(SBS_ETHERNET_PHY_RMII);
}

/* Dummy read to sync with ETH */
(void)SBS->PMCR;

/* Ethernet Software reset */
/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
/* After reset all the registers holds their respective reset values */
SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);

/* Get tick */
tickstart = HAL_GetTick();

/* Wait for software reset */
while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
{
if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
{
/* Set Error Code */
heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
/* Set State as Error */
heth->gState = HAL_ETH_STATE_ERROR;
/* Return Error */
return HAL_ERROR;
}
}

我已经排查了很多内容:RCC、以太网控制寄存器等等,但不知道为什么 SWR 位无法清零。
我也按照网上流传的手册修改了ethernetif.c与lwip.c。我的工程不是只跑以太网,还同时启用多个外设,所以引脚分配和官方示例、Github 工程并不相同。
请嵌入式大神帮忙,

classroom 发表于 2026-10-19 11:04 | 显示全部楼层
根据RMII规范,SWR位清除的前提是所有活动时钟域都必须有正确的PHY输入时钟。应先用示波器确认Nucleo-H7S3L8板上的RMII_REF_CLK(PA1)是否有稳定的50MHz信号,而不是只检查RCC配置寄存器。
cr315 发表于 2026-10-19 11:40 | 显示全部楼层
“引脚分配和官方示例不同”很可能就是根因。Nucleo-H7S3L8的以太网引脚经过SB(焊桥)连接到PHY,如果CubeMX里重新分配了某些引脚,或者硬件上SB被改过,RMII时钟路径可能被切断。
duo点 发表于 2026-10-19 12:16 | 显示全部楼层
LAN8742A的NRST引脚与MCU的NRST连在一起时,PHY的复位释放时间需要超过25ms才能调用HAL_ETH_Init。如果MSP初始化在PHY就绪前就启动了ETH,SWR就会因缺少时钟而超时。
elephant00 发表于 2026-10-19 11:05 | 显示全部楼层
代码里对SYSCFG->PMCR做了一次哑读,这是为了解决APB4预分频较大时配置未生效的问题。但需要确认H7S3L8上这个寄存器写入的MII/RMII选择是否真正被ETH外设采样到了。
flycamelaaa 发表于 2026-10-19 13:06 | 显示全部楼层
PHY的LED引脚极性配置会影响参考时钟输出。LAN8742的LED引脚如果外部上下拉不对,可能导致内部振荡器不起振,MAC侧就收不到50MHz时钟,SWR***等不到清除。
jcky001 发表于 2026-10-19 13:39 | 显示全部楼层
在FreeRTOS环境下,如果HAL_GetTick的时基被中断优先级问题干扰,超时判断可能不可靠。但SWR“始终无法清零”更像是硬件时钟根本不存在,而不是超时阈值的问题。
onlycook 发表于 2026-10-19 14:17 | 显示全部楼层
可以尝试在SET_BIT之后加一句读取DMAMR的强制操作,确保写操作真正到达外设总线。H7系列的ETH外设挂在AXI总线上,如果MPU把ETH寄存器区域配置成了Non-shareable或Device但写缓冲未刷新,写操作可能被延迟。
powerantone 发表于 2026-10-19 15:20 | 显示全部楼层
HAL_ETH_Init被调用两次会导致HardFault或异常。检查工程里MX_ETH_Init和手动调用的HAL_ETH_Init是否重复,重复初始化时第一次已经把SWR置位了,第二次再等它清零时状态机可能已经乱了。
probedog 发表于 2026-10-19 16:35 | 显示全部楼层
H7S3L8的ETH MAC需要三个时钟:AHB总线时钟、ETH TX时钟、ETH RX时钟。如果为了给其他外设省电或分频,把某个ETH时钟关掉了,SWR就不会完成。用CubeMX检查RCC里ETH相关的时钟树分支是否都使能了。
solty 发表于 2026-10-19 17:12 | 显示全部楼层
修改ethernetif.c和lwip.c来适配工程时,如果修改中涉及low_level_init的调用时机,可能把HAL_ETH_Init放在了PHY硬件复位完成之前。先确保PHY的复位引脚时序正确,再调用MAC初始化。
spicy 发表于 2026-10-19 17:45 | 显示全部楼层
Nucleo-H7S3L8的以太网连接器如果是带LED的RJ45,某些批次连接器的LED引脚会通过内部电路影响PHY的REF_CLK输出。换一个不带LED或LED极性兼容的连接器试试,有案例就是靠换连接器解决了完全相同的SWR超时。
stormwind123 发表于 2026-10-19 19:09 | 显示全部楼层
如果用的是自定义PHY地址或非LAN8742的PHY,SMI通信可能根本没建立。虽然SWR不直接依赖SMI,但PHY如果没有被正确配置为RMII模式并输出时钟,MAC就等不到时钟。先用HAL_ETH_ReadPHYRegister读一下PHY的ID寄存器,确认MDIO链路是通的。
七毛钱 发表于 2026-10-19 19:50 | 显示全部楼层
检查MPU配置。如果ETH的DMA描述符或缓冲区所在的RAM区域被配置成了Cacheable且没有做Cache维护,DMA操作可能写到了错误的地方,导致MAC内部状态机异常。虽然这通常影响的是数据传输而不是SWR清除,但状态机异常时寄存器行为可能不可预测。
今天会画卧蚕吗 发表于 2026-10-19 20:10 | 显示全部楼层
在调试器里直接看DMAMR寄存器的值:如果SWR位始终是1,同时MAC配置寄存器(如MACCAR)读出来全是0或全是F,说明MAC时钟域完全没有运行。如果MACCAR能读到合理的复位值,说明时钟在走但复位握手有问题,方向就不同了。
内政奇才 发表于 2026-10-19 21:37 | 显示全部楼层
建议暂时把工程精简到只跑ETH + LwIP,不要同时启用其他外设。多外设同时初始化时,如果某个外设的时钟使能顺序或GPIO复用配置与ETH引脚冲突,可能覆盖掉ETH的MCO或复用功能,导致时钟路径断开。
又见江南雨 发表于 2026-10-19 21:27 | 显示全部楼层
检查ETH外设的时钟源是否已经正确使能,如果MAC内核没有时钟信号,寄存器写入操作可能无法生效,导致SWR位一直置位。
在海边聆听 发表于 2026-10-19 21:55 | 显示全部楼层
确认DMA描述符缓冲区的内存属性配置,STM32H7系列具有Cache,如果描述符所在内存区域未设置为非缓存或未经过Cache一致性处理,DMA可能读取到旧数据。
才没有脸红 发表于 2026-10-19 22:26 | 显示全部楼层
验证PHY芯片的复位引脚状态,如果PHY处于硬件复位状态或未正常启动,MAC层与PHY层的通信链路未建立,可能导致内部逻辑卡死在复位等待状态。
故里说长安 发表于 2026-10-20 10:13 | 显示全部楼层
检查MPU的配置,确保以太网相关的RAM区域权限设置正确,错误的MPU配置可能阻止DMA控制器访问描述符或数据包缓冲区。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

105

主题

709

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部