Преглед изворни кода

ethernet: work with cache disabled

add ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE flag, make ethenret driver
possible to work when cache disabled

Closes https://github.com/espressif/esp-idf/issues/4406
morris пре 6 година
родитељ
комит
274b0b8d8a

+ 4 - 2
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

+ 15 - 4
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);

+ 5 - 2
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;
 }