ESP32:如何修复 emac_esp32_init(): reset timeout

问题

运行基于 ESP32 的以太网应用程序时,你会看到以下错误日志或崩溃:

esp.emac
E (443) esp.emac: emac_esp32_init(428): reset timeout
E (443) esp_eth: esp_eth_driver_install(228): init mac failed

解决方案

问题在于你使用的是带有外部 RMII 时钟输入 (EMAC_CLK_EXT_IN) 的以太网 MAC,GPIO0 上没有输入时钟信号,而 GPIO0 是 ESP32 上唯一可用于 RMII 时钟输入的 GPIO

使用示波器或逻辑分析仪检查时钟。如果在 GPIO0 上看不到时钟信号,你需要提供一个时钟信号。

究竟是什么导致了错误?

emac_esp32_init() 期间,ESP-IDF 会软复位 ESP32 中的以太网 MAC 外设,然后等待复位完成。它会等待最多 100 毫秒。如果复位在此时间内未完成,则会引发 reset timeout 错误。

这是来自 ESP-IDF 源代码的相关代码片段:

emac_reset_snippet.c
emac_hal_reset(&emac->hal);
uint32_t to = 0;
for (to = 0; to < emac->sw_reset_timeout_ms / 10; to++) {
    if (emac_hal_is_reset_done(&emac->hal)) {
        break;
    }
    vTaskDelay(pdMS_TO_TICKS(10));
}
ESP_GOTO_ON_FALSE(to < emac->sw_reset_timeout_ms / 10, ESP_ERR_TIMEOUT, err, TAG, "reset timeout");

Check out similar posts by category: ESP32, ESP-IDF, C/C++, Networking