diff --git a/components/esp_eth/include/esp_eth_mac.h b/components/esp_eth/include/esp_eth_mac.h index 4318b2b64..00094d8b0 100644 --- a/components/esp_eth/include/esp_eth_mac.h +++ b/components/esp_eth/include/esp_eth_mac.h @@ -24,7 +24,6 @@ extern "C" { #include "driver/spi_master.h" #endif - /** * @brief Ethernet MAC * @@ -252,8 +251,11 @@ typedef struct { uint32_t rx_task_prio; /*!< Priority of the receive task */ int smi_mdc_gpio_num; /*!< SMI MDC GPIO number */ int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number */ + uint32_t flags; /*!< Flags that specify extra capability for mac driver */ } eth_mac_config_t; +#define ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE (1 << 0) /*!< MAC driver can work when cache is disabled */ + /** * @brief Default configuration for Ethernet MAC object * @@ -265,6 +267,7 @@ typedef struct { .rx_task_prio = 15, \ .smi_mdc_gpio_num = 23, \ .smi_mdio_gpio_num = 18, \ + .flags = 0, \ } #if CONFIG_ETH_USE_ESP32_EMAC @@ -313,7 +316,6 @@ typedef struct { esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config); #endif - #if CONFIG_ETH_USE_OPENETH esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config); #endif // CONFIG_ETH_USE_OPENETH diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index 4e61078f6..64025c4bd 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -171,7 +171,8 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_ esp_eth_mac_t *mac = config->mac; esp_eth_phy_t *phy = config->phy; ETH_CHECK(mac && phy, "can't set eth->mac or eth->phy to null", err, ESP_ERR_INVALID_ARG); - esp_eth_driver_t *eth_driver = calloc(1, sizeof(esp_eth_driver_t)); + // eth_driver contains an atomic variable, which should not be put in PSRAM + esp_eth_driver_t *eth_driver = heap_caps_calloc(1, sizeof(esp_eth_driver_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ETH_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM); atomic_init(ð_driver->ref_count, 1); eth_driver->mac = mac; diff --git a/components/esp_eth/src/esp_eth_mac_esp32.c b/components/esp_eth/src/esp_eth_mac_esp32.c index 6f7941384..b1d28e0e5 100644 --- a/components/esp_eth/src/esp_eth_mac_esp32.c +++ b/components/esp_eth/src/esp_eth_mac_esp32.c @@ -358,6 +358,7 @@ static esp_err_t emac_esp32_del(esp_eth_mac_t *mac) return ESP_OK; } +// To achieve a better performance, we put the ISR always in IRAM IRAM_ATTR void emac_esp32_isr_handler(void *args) { emac_hal_context_t *hal = (emac_hal_context_t *)args; @@ -371,11 +372,16 @@ IRAM_ATTR void emac_esp32_isr_handler(void *args) esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config) { + esp_err_t ret_code = ESP_OK; esp_eth_mac_t *ret = NULL; void *descriptors = NULL; emac_esp32_t *emac = NULL; MAC_CHECK(config, "can't set mac config to null", err, NULL); - emac = calloc(1, sizeof(emac_esp32_t)); + if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) { + emac = heap_caps_calloc(1, sizeof(emac_esp32_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + } else { + emac = calloc(1, sizeof(emac_esp32_t)); + } MAC_CHECK(emac, "calloc emac failed", err, NULL); /* alloc memory for ethernet dma descriptor */ uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) + @@ -416,9 +422,14 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config) emac->parent.transmit = emac_esp32_transmit; emac->parent.receive = emac_esp32_receive; /* Interrupt configuration */ - MAC_CHECK(esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, emac_esp32_isr_handler, - &emac->hal, &(emac->intr_hdl)) == ESP_OK, - "alloc emac interrupt failed", err, NULL); + if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) { + ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, + emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl)); + } else { + ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0, + emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl)); + } + MAC_CHECK(ret_code == ESP_OK, "alloc emac interrupt failed", err, NULL); #ifdef CONFIG_PM_ENABLE MAC_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "emac_esp32", &emac->pm_lock) == ESP_OK, "create pm lock failed", err, NULL); diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index b3765d878..87b218047 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -208,6 +208,7 @@ static void on_eth_event(void *esp_netif, esp_event_base_t event_base, static esp_eth_handle_t s_eth_handle = NULL; static esp_eth_mac_t *s_mac = NULL; static esp_eth_phy_t *s_phy = NULL; +static void *s_eth_glue = NULL; static void start(void) { @@ -275,7 +276,8 @@ static void start(void) esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy); ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); // combine driver with netif - esp_netif_attach(netif, esp_eth_new_netif_glue(s_eth_handle)); + s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); + esp_netif_attach(netif, s_eth_glue); esp_eth_start(s_eth_handle); s_connection_name = "Ethernet"; } @@ -288,11 +290,12 @@ static void stop(void) ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); #endif ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle)); + ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue)); + ESP_ERROR_CHECK(esp_eth_clear_default_handlers(s_example_esp_netif)); ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle)); ESP_ERROR_CHECK(s_phy->del(s_phy)); ESP_ERROR_CHECK(s_mac->del(s_mac)); - esp_eth_clear_default_handlers(s_example_esp_netif); esp_netif_destroy(s_example_esp_netif); s_example_esp_netif = NULL; }