Merge branch 'bugfix/eth_remove_dep_on_netif' into 'master'

ethernet: remove dependency on esp_netif && add reference counter

Closes IDF-1104

See merge request espressif/esp-idf!6711
This commit is contained in:
Angus Gratton 2019-11-27 16:08:31 +08:00
commit 89f1786754
32 changed files with 645 additions and 336 deletions

View file

@ -1,10 +1,20 @@
idf_build_get_property(components_to_build BUILD_COMPONENTS)
set(srcs)
set(include)
set(priv_requires)
# If Ethernet disabled in Kconfig, this is a config-only component
if(CONFIG_ETH_ENABLED)
set(srcs "src/esp_eth.c")
set(include "include")
set(priv_requires "driver" "log") # require "driver" for using some GPIO APIs
# esp_netif related
if(esp_netif IN_LIST components_to_build)
list(APPEND srcs "src/esp_eth_netif_glue.c")
list(APPEND priv_requires "esp_netif")
endif()
if(CONFIG_ETH_USE_ESP32_EMAC)
list(APPEND srcs "src/esp_eth_mac_esp32.c"
@ -26,5 +36,8 @@ endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${include}
REQUIRES "esp_event"
PRIV_REQUIRES "esp_netif" "driver" "log")
REQUIRES "esp_event" # For using "ESP_EVENT_DECLARE_BASE" in header file
PRIV_REQUIRES ${priv_requires})
# uses C11 atomic feature
set_source_files_properties(src/esp_eth.c PROPERTIES COMPILE_FLAGS -std=gnu11)

View file

@ -15,3 +15,6 @@ endif
ifndef CONFIG_ETH_USE_OPENETH
COMPONENT_OBJEXCLUDE += src/esp_eth_mac_openeth.o
endif
# uses C11 atomic feature
src/esp_eth.o: CFLAGS += -std=gnu11

View file

@ -62,7 +62,7 @@ typedef struct {
* - ESP_FAIL: error occurred when inputting buffer to upper stack
*
*/
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length);
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv);
/**
* @brief Callback function invoked when lowlevel initialization is finished
@ -116,33 +116,68 @@ typedef struct {
*/
esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_t *out_hdl);
/**
* @brief Start ethernet driver **ONLY** in standalone mode, i.e. without TCP/IP stack
*
* Note that ethernet driver is typically started as soon as it is attached to esp-netif.
* This API should only be called if ethernet is used separately without esp-netif, for example
* when esp_eth_config_t.stack_input is not NULL.
*
* @param[in] eth_handle handle of Ethernet driver
*
* @return
* - ESP_OK: starts ethernet driver
* - ESP_ERR_INVALID_STATE: if event loop hasn't been initialized
*/
esp_err_t esp_eth_driver_start(esp_eth_handle_t eth_handle);
/**
* @brief Uninstall Ethernet driver
* @note It's not recommended to uninstall Ethernet driver unless it won't get used any more in application code.
* To uninstall Ethernet driver, you have to make sure, all references to the driver are released.
* Ethernet driver can only be uninstalled successfully when reference counter equals to one.
*
* @param[in] hdl: handle of Ethernet driver
*
* @return
* - ESP_OK: uninstall esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: uninstall esp_eth driver failed because of some invalid argument
* - ESP_ERR_INVALID_STATE: uninstall esp_eth driver failed because it has more than one reference
* - ESP_FAIL: uninstall esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl);
/**
* @brief Start Ethernet driver **ONLY** in standalone mode (i.e. without TCP/IP stack)
*
* @note This API will start driver state machine and internal software timer (for checking link status).
*
* @param[in] hdl handle of Ethernet driver
*
* @return
* - ESP_OK: start esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: start esp_eth driver failed because of some invalid argument
* - ESP_FAIL: start esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_start(esp_eth_handle_t hdl);
/**
* @brief Stop Ethernet driver
*
* @note This function does the oppsite operation of `esp_eth_start`.
*
* @param[in] hdl handle of Ethernet driver
* @return
* - ESP_OK: stop esp_eth driver successfully
* - ESP_ERR_INVALID_ARG: stop esp_eth driver failed because of some invalid argument
* - ESP_FAIL: stop esp_eth driver failed because some other error occurred
*/
esp_err_t esp_eth_stop(esp_eth_handle_t hdl);
/**
* @brief Update Ethernet data input path (i.e. specify where to pass the input buffer)
*
* @note After install driver, Ethernet still don't know where to deliver the input buffer.
* In fact, this API registers a callback function which get invoked when Ethernet received new packets.
*
* @param[in] hdl handle of Ethernet driver
* @param[in] stack_input function pointer, which does the actual process on incoming packets
* @param[in] priv private resource, which gets passed to `stack_input` callback without any modification
* @return
* - ESP_OK: update input path successfully
* - ESP_ERR_INVALID_ARG: update input path failed because of some invalid argument
* - ESP_FAIL: update input path failed because some other error occurred
*/
esp_err_t esp_eth_update_input_path(
esp_eth_handle_t hdl,
esp_err_t (*stack_input)(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv),
void *priv);
/**
* @brief General Transmit
*
@ -155,7 +190,7 @@ esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl);
* - ESP_ERR_INVALID_ARG: transmit frame buffer failed because of some invalid argument
* - ESP_FAIL: transmit frame buffer failed because some other error occurred
*/
esp_err_t esp_eth_transmit(void* hdl, void *buf, uint32_t length);
esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, uint32_t length);
/**
* @brief General Receive
@ -191,20 +226,29 @@ esp_err_t esp_eth_receive(esp_eth_handle_t hdl, uint8_t *buf, uint32_t *length);
esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data);
/**
* @brief Register default ethernet handlers
*
* @param[in] esp_netif esp network interface handle created for this driver
* (note: appropriate ethernet handle not yet properly initialized when setting up
* default handlers)
*/
esp_err_t esp_eth_set_default_handlers(void* esp_netif);
* @brief Increase Ethernet driver reference
* @note Ethernet driver handle can be obtained by os timer, netif, etc.
* It's dangerous when thread A is using Ethernet but thread B uninstall the driver.
* Using reference counter can prevent such risk, but care should be taken, when you obtain Ethernet driver,
* this API must be invoked so that the driver won't be uninstalled during your using time.
*
*
* @param[in] hdl: handle of Ethernet driver
* @return
* - ESP_OK: increase reference successfully
* - ESP_ERR_INVALID_ARG: increase reference failed because of some invalid argument
*/
esp_err_t esp_eth_increase_reference(esp_eth_handle_t hdl);
/**
* @brief Unregister default ethernet handlers
*
* @param[in] esp_netif esp network interface handle created for this driver
*/
esp_err_t esp_eth_clear_default_handlers(void* esp_netif);
* @brief Decrease Ethernet driver reference
*
* @param[in] hdl: handle of Ethernet driver
* @return
* - ESP_OK: increase reference successfully
* - ESP_ERR_INVALID_ARG: increase reference failed because of some invalid argument
*/
esp_err_t esp_eth_decrease_reference(esp_eth_handle_t hdl);
#ifdef __cplusplus
}

View file

@ -18,9 +18,8 @@ extern "C" {
#endif
#include <stdbool.h>
#include <stdatomic.h>
#include "sdkconfig.h"
#include "esp_eth_com.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif
@ -37,12 +36,6 @@ typedef struct esp_eth_mac_s esp_eth_mac_t;
*
*/
struct esp_eth_mac_s {
/**
* @brief Reference count of MAC instance
*
*/
atomic_int ref_count;
/**
* @brief Set mediator for Ethernet MAC
*
@ -322,17 +315,6 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
#if CONFIG_ETH_USE_OPENETH
/**
* @brief Create OpenETH MAC instance
*
* @note This API is only used for qemu simulation
*
* @param config: Ethernet MAC configuration
*
* @return
* - instance: create MAC instance successfully
* - NULL: create MAC instance failed because some error occurred
*/
esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config);
#endif // CONFIG_ETH_USE_OPENETH

View file

@ -0,0 +1,66 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_eth.h"
/**
* @brief Create a netif glue for Ethernet driver
* @note netif glue is used to attach io driver to TCP/IP netif
*
* @param eth_hdl Ethernet driver handle
* @return glue object, which inherits esp_netif_driver_base_t
*/
void *esp_eth_new_netif_glue(esp_eth_handle_t eth_hdl);
/**
* @brief Delete netif glue of Ethernet driver
*
* @param glue netif glue
* @return -ESP_OK: delete netif glue successfully
*/
esp_err_t esp_eth_del_netif_glue(void *glue);
/**
* @brief Register default IP layer handlers for Ethernet
*
* @note: Ethernet handle might not yet properly initialized when setting up these default handlers
*
* @param[in] esp_netif esp network interface handle created for Ethernet driver
* @return
* - ESP_ERR_INVALID_ARG: invalid parameter (esp_netif is NULL)
* - ESP_OK: set default IP layer handlers successfully
* - others: other failure occurred during register esp_event handler
*/
esp_err_t esp_eth_set_default_handlers(void *esp_netif);
/**
* @brief Unregister default IP layer handlers for Ethernet
*
* @param[in] esp_netif esp network interface handle created for Ethernet driver
* @return
* - ESP_ERR_INVALID_ARG: invalid parameter (esp_netif is NULL)
* - ESP_OK: clear default IP layer handlers successfully
* - others: other failure occurred during unregister esp_event handler
*/
esp_err_t esp_eth_clear_default_handlers(void *esp_netif);
#ifdef __cplusplus
}
#endif

View file

@ -18,9 +18,8 @@ extern "C" {
#endif
#include <stdbool.h>
#include <stdatomic.h>
#include "sdkconfig.h"
#include "esp_eth_com.h"
#include "sdkconfig.h"
/**
* @brief Ethernet PHY
@ -33,12 +32,6 @@ typedef struct esp_eth_phy_s esp_eth_phy_t;
*
*/
struct esp_eth_phy_s {
/**
* @brief Reference count of PHY instance
*
*/
atomic_int ref_count;
/**
* @brief Set mediator for PHY
*

View file

@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/cdefs.h>
#include <stdatomic.h>
#include "esp_log.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "esp_netif.h"
#include "tcpip_adapter_compatible/tcpip_adapter_compat.h"
static const char *TAG = "esp_eth";
#define ETH_CHECK(a, str, goto_tag, ret_value, ...) \
@ -46,7 +45,6 @@ ESP_EVENT_DEFINE_BASE(ETH_EVENT);
* In the callback, user can do any low level operations (e.g. enable/disable crystal clock).
*/
typedef struct {
esp_netif_driver_base_t base;
esp_eth_mediator_t mediator;
esp_eth_phy_t *phy;
esp_eth_mac_t *mac;
@ -54,7 +52,9 @@ typedef struct {
eth_speed_t speed;
eth_duplex_t duplex;
eth_link_t link;
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length);
atomic_int ref_count;
void *priv;
esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv);
esp_err_t (*on_lowlevel_init_done)(esp_eth_handle_t eth_handle);
esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle);
} esp_eth_driver_t;
@ -85,10 +85,11 @@ static esp_err_t eth_phy_reg_write(esp_eth_mediator_t *eth, uint32_t phy_addr, u
static esp_err_t eth_stack_input(esp_eth_mediator_t *eth, uint8_t *buffer, uint32_t length)
{
esp_eth_driver_t *eth_driver = __containerof(eth, esp_eth_driver_t, mediator);
if (!eth_driver->stack_input) {
return esp_netif_receive(eth_driver->base.netif, buffer, length, NULL);
if (eth_driver->stack_input) {
return eth_driver->stack_input((esp_eth_handle_t)eth_driver, buffer, length, eth_driver->priv);
} else {
return eth_driver->stack_input((esp_eth_handle_t)eth_driver, buffer, length);
free(buffer);
return ESP_OK;
}
}
@ -148,37 +149,9 @@ static void eth_check_link_timer_cb(TimerHandle_t xTimer)
{
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)pvTimerGetTimerID(xTimer);
esp_eth_phy_t *phy = eth_driver->phy;
/* add reference to prevent other thread deleting the phy instance */
atomic_fetch_add(&phy->ref_count, 1);
esp_eth_increase_reference(eth_driver);
phy->get_link(phy);
/* only the timer obtains the instance, i.e. all other references to this phy has been released */
if (atomic_load(&phy->ref_count) == 1) {
phy->del(phy); // since this phy doesn't have other owners, delete it
} else {
atomic_fetch_sub(&phy->ref_count, 1);
}
}
static esp_err_t esp_eth_post_attach_driver_start(esp_netif_t * esp_netif, void * args)
{
uint8_t eth_mac[6];
esp_eth_driver_t *eth_driver = args;
eth_driver->base.netif = esp_netif;
// Set driver related config to esp-netif
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = eth_driver,
.transmit = esp_eth_transmit,
.driver_free_rx_buffer = NULL
};
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
esp_eth_ioctl(eth_driver, ETH_CMD_G_MAC_ADDR, eth_mac);
ESP_LOGI(TAG, "%x %x %x %x %x %x", eth_mac[0], eth_mac[1], eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
esp_netif_set_mac(esp_netif, eth_mac);
ESP_LOGI(TAG, "ETH netif started");
return esp_eth_driver_start(eth_driver);
esp_eth_decrease_reference(eth_driver);
}
////////////////////////////////User face APIs////////////////////////////////////////////////
@ -186,21 +159,6 @@ static esp_err_t esp_eth_post_attach_driver_start(esp_netif_t * esp_netif, void
// Different Ethernet driver instance is identified with a unique handle.
// It's helpful for us to support multiple Ethernet port on ESP32.
//////////////////////////////////////////////////////////////////////////////////////////////
esp_err_t esp_eth_driver_start(esp_eth_handle_t eth_handle)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = eth_handle;
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS, "start eth_link_timer failed", err_start_timer, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_START event failed", err_event, ESP_FAIL);
return ret;
err_start_timer:
xTimerDelete(eth_driver->check_link_timer, 0);
err_event:
esp_eth_driver_uninstall(eth_driver);
return ret;
}
esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_t *out_hdl)
{
@ -212,10 +170,9 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_
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_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM);
atomic_init(&eth_driver->ref_count, 1);
eth_driver->mac = mac;
eth_driver->phy = phy;
atomic_fetch_add(&phy->ref_count, 1);
atomic_fetch_add(&mac->ref_count, 1);
eth_driver->link = ETH_LINK_DOWN;
eth_driver->duplex = ETH_DUPLEX_HALF;
eth_driver->speed = ETH_SPEED_10M;
@ -235,9 +192,14 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_
eth_driver->check_link_timer = xTimerCreate("eth_link_timer", pdMS_TO_TICKS(config->check_link_period_ms), pdTRUE,
eth_driver, eth_check_link_timer_cb);
ETH_CHECK(eth_driver->check_link_timer, "create eth_link_timer failed", err_create_timer, ESP_FAIL);
eth_driver->base.post_attach = esp_eth_post_attach_driver_start;
*out_hdl = (esp_eth_handle_t)eth_driver;
// for backward compatible to 4.0, and will get removed in 5.0
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
extern esp_err_t tcpip_adapter_compat_start_eth(void *eth_driver);
tcpip_adapter_compat_start_eth(eth_driver);
#endif
return ESP_OK;
err_create_timer:
phy->deinit(phy);
@ -245,8 +207,6 @@ err_init_phy:
mac->deinit(mac);
err_init_mac:
err_mediator:
atomic_fetch_sub(&phy->ref_count, 1);
atomic_fetch_sub(&mac->ref_count, 1);
free(eth_driver);
err:
return ret;
@ -257,22 +217,66 @@ esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl)
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
// don't uninstall driver unless there's only one reference
ETH_CHECK(atomic_load(&eth_driver->ref_count) == 1,
"more than one reference to ethernet driver", err, ESP_ERR_INVALID_STATE);
esp_eth_mac_t *mac = eth_driver->mac;
esp_eth_phy_t *phy = eth_driver->phy;
ETH_CHECK(xTimerDelete(eth_driver->check_link_timer, 0) == pdPASS, "delete eth_link_timer failed", err, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL);
ETH_CHECK(phy->deinit(phy) == ESP_OK, "deinit phy failed", err, ESP_FAIL);
ETH_CHECK(mac->deinit(mac) == ESP_OK, "deinit mac failed", err, ESP_FAIL);
atomic_fetch_sub(&phy->ref_count, 1);
atomic_fetch_sub(&mac->ref_count, 1);
free(eth_driver);
return ESP_OK;
err:
return ret;
}
esp_err_t esp_eth_transmit(void* hdl, void *buf, uint32_t length)
esp_err_t esp_eth_start(esp_eth_handle_t hdl)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS,
"start eth_link_timer failed", err, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_START event failed", err_event, ESP_FAIL);
return ESP_OK;
err_event:
xTimerStop(eth_driver->check_link_timer, 0);
err:
return ret;
}
esp_err_t esp_eth_stop(esp_eth_handle_t hdl)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS,
"stop eth_link_timer failed", err, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL);
return ESP_OK;
err:
return ret;
}
esp_err_t esp_eth_update_input_path(
esp_eth_handle_t hdl,
esp_err_t (*stack_input)(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv),
void *priv)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
eth_driver->priv = priv;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
eth_driver->stack_input = stack_input;
return ESP_OK;
err:
return ret;
}
esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, uint32_t length)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
@ -334,54 +338,24 @@ err:
return ret;
}
esp_err_t esp_eth_clear_default_handlers(void* esp_netif)
esp_err_t esp_eth_increase_reference(esp_eth_handle_t hdl)
{
esp_err_t ret;
ETH_CHECK(esp_netif, "esp-netif handle can't be null", fail, ESP_ERR_INVALID_ARG);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip);
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
atomic_fetch_add(&eth_driver->ref_count, 1);
return ESP_OK;
fail:
err:
return ret;
}
esp_err_t esp_eth_set_default_handlers(void* esp_netif)
esp_err_t esp_eth_decrease_reference(esp_eth_handle_t hdl)
{
esp_err_t ret;
ETH_CHECK(esp_netif, "esp-netif handle can't be null", fail, ESP_ERR_INVALID_ARG);
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
atomic_fetch_sub(&eth_driver->ref_count, 1);
return ESP_OK;
fail:
esp_eth_clear_default_handlers(esp_netif);
err:
return ret;
}

View file

@ -709,11 +709,9 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac)
static esp_err_t emac_dm9051_del(esp_eth_mac_t *mac)
{
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
if (atomic_fetch_sub(&mac->ref_count, 1) == 1) {
vTaskDelete(emac->rx_task_hdl);
vSemaphoreDelete(emac->spi_lock);
free(emac);
}
vTaskDelete(emac->rx_task_hdl);
vSemaphoreDelete(emac->spi_lock);
free(emac);
return ESP_OK;
}
@ -745,7 +743,6 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
emac->parent.set_promiscuous = emac_dm9051_set_promiscuous;
emac->parent.transmit = emac_dm9051_transmit;
emac->parent.receive = emac_dm9051_receive;
atomic_init(&emac->parent.ref_count, 1);
/* create mutex */
emac->spi_lock = xSemaphoreCreateMutex();
MAC_CHECK(emac->spi_lock, "create lock failed", err, NULL);

View file

@ -334,19 +334,17 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac)
static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
{
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
if (atomic_fetch_sub(&mac->ref_count, 1) == 1) {
esp_intr_free(emac->intr_hdl);
vTaskDelete(emac->rx_task_hdl);
int i = 0;
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
free(emac->hal.rx_buf[i]);
}
for (i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
free(emac->hal.tx_buf[i]);
}
free(emac->hal.descriptors);
free(emac);
esp_intr_free(emac->intr_hdl);
vTaskDelete(emac->rx_task_hdl);
int i = 0;
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
free(emac->hal.rx_buf[i]);
}
for (i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
free(emac->hal.tx_buf[i]);
}
free(emac->hal.descriptors);
free(emac);
return ESP_OK;
}
@ -407,7 +405,6 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
emac->parent.set_promiscuous = emac_esp32_set_promiscuous;
emac->parent.transmit = emac_esp32_transmit;
emac->parent.receive = emac_esp32_receive;
atomic_init(&emac->parent.ref_count, 1);
/* 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,

View file

@ -66,7 +66,7 @@ static esp_err_t emac_opencores_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32
static IRAM_ATTR void emac_opencores_isr_handler(void *args)
{
emac_opencores_t *emac = (emac_opencores_t *) args;
emac_opencores_t *emac = (emac_opencores_t*) args;
BaseType_t high_task_wakeup;
uint32_t status = REG_READ(OPENETH_INT_SOURCE_REG);
@ -94,7 +94,7 @@ static void emac_opencores_rx_task(void *arg)
uint32_t length = 0;
while (1) {
if (ulTaskNotifyTake(pdFALSE, portMAX_DELAY)) {
while (true) {
while(true) {
buffer = (uint8_t *)malloc(ETH_MAX_PACKET_SIZE);
length = ETH_MAX_PACKET_SIZE;
if (emac_opencores_receive(&emac->parent, buffer, &length) == ESP_OK) {
@ -243,7 +243,7 @@ static esp_err_t emac_opencores_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint3
while (bytes_remaining > 0) {
uint32_t will_write = MIN(bytes_remaining, DMA_BUF_SIZE);
memcpy(emac->tx_buf[emac->cur_tx_desc], buf, will_write);
openeth_tx_desc_t *desc_ptr = openeth_tx_desc(emac->cur_tx_desc);
openeth_tx_desc_t* desc_ptr = openeth_tx_desc(emac->cur_tx_desc);
openeth_tx_desc_t desc_val = *desc_ptr;
desc_val.wr = (emac->cur_tx_desc == TX_BUF_COUNT - 1);
desc_val.len = will_write;
@ -294,7 +294,7 @@ static esp_err_t emac_opencores_init(esp_eth_mac_t *mac)
esp_eth_mediator_t *eth = emac->eth;
MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL);
MAC_CHECK(esp_read_mac(emac->addr, ESP_MAC_ETH) == ESP_OK, "fetch ethernet mac address failed", err, ESP_FAIL);
// Sanity check
if (REG_READ(OPENETH_MODER_REG) != OPENETH_MODER_DEFAULT) {
ESP_LOGE(TAG, "CONFIG_ETH_USE_OPENETH should only be used when running in QEMU.");
@ -323,17 +323,15 @@ static esp_err_t emac_opencores_deinit(esp_eth_mac_t *mac)
static esp_err_t emac_opencores_del(esp_eth_mac_t *mac)
{
emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent);
if (atomic_fetch_sub(&mac->ref_count, 1) == 1) {
esp_intr_free(emac->intr_hdl);
vTaskDelete(emac->rx_task_hdl);
for (int i = 0; i < RX_BUF_COUNT; i++) {
free(emac->rx_buf[i]);
}
for (int i = 0; i < TX_BUF_COUNT; i++) {
free(emac->tx_buf[i]);
}
free(emac);
esp_intr_free(emac->intr_hdl);
vTaskDelete(emac->rx_task_hdl);
for (int i = 0; i < RX_BUF_COUNT; i++) {
free(emac->rx_buf[i]);
}
for (int i = 0; i < TX_BUF_COUNT; i++) {
free(emac->tx_buf[i]);
}
free(emac);
return ESP_OK;
}
@ -380,8 +378,7 @@ esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config)
emac->parent.set_promiscuous = emac_opencores_set_promiscuous;
emac->parent.transmit = emac_opencores_transmit;
emac->parent.receive = emac_opencores_receive;
atomic_init(&emac->parent.ref_count, 1);
// Initialize the interrupt
MAC_CHECK(esp_intr_alloc(OPENETH_INTR_SOURCE, ESP_INTR_FLAG_IRAM, emac_opencores_isr_handler,
emac, &(emac->intr_hdl)) == ESP_OK,

View file

@ -0,0 +1,134 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdlib.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_eth_netif_glue.h"
#include "esp_event.h"
#include "esp_log.h"
const static char *TAG = "esp_eth.netif.glue";
typedef struct {
esp_netif_driver_base_t base;
esp_eth_handle_t eth_driver;
} esp_eth_netif_glue_t;
static esp_err_t eth_input_to_netif(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv)
{
return esp_netif_receive((esp_netif_t *)priv, buffer, length, NULL);
}
static esp_err_t esp_eth_post_attach(esp_netif_t *esp_netif, void *args)
{
uint8_t eth_mac[6];
esp_eth_netif_glue_t *glue = (esp_eth_netif_glue_t *)args;
glue->base.netif = esp_netif;
esp_eth_update_input_path(glue->eth_driver, eth_input_to_netif, esp_netif);
// set driver related config to esp-netif
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = glue->eth_driver,
.transmit = esp_eth_transmit,
.driver_free_rx_buffer = NULL
};
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
esp_eth_ioctl(glue->eth_driver, ETH_CMD_G_MAC_ADDR, eth_mac);
ESP_LOGI(TAG, "%02x:%02x:%02x:%02x:%02x:%02x", eth_mac[0], eth_mac[1],
eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
esp_netif_set_mac(esp_netif, eth_mac);
ESP_LOGI(TAG, "ethernet attached to netif");
return ESP_OK;
}
void *esp_eth_new_netif_glue(esp_eth_handle_t eth_hdl)
{
esp_eth_netif_glue_t *glue = calloc(1, sizeof(esp_eth_netif_glue_t));
if (!glue) {
ESP_LOGE(TAG, "create netif glue failed");
return NULL;
}
glue->eth_driver = eth_hdl;
glue->base.post_attach = esp_eth_post_attach;
esp_eth_increase_reference(eth_hdl);
return &glue->base;
}
esp_err_t esp_eth_del_netif_glue(void *g)
{
esp_eth_netif_glue_t *glue = (esp_eth_netif_glue_t *)g;
esp_eth_decrease_reference(glue->eth_driver);
free(glue);
return ESP_OK;
}
esp_err_t esp_eth_clear_default_handlers(void *esp_netif)
{
if (!esp_netif) {
ESP_LOGE(TAG, "esp-netif handle can't be null");
return ESP_ERR_INVALID_ARG;
}
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip);
return ESP_OK;
}
esp_err_t esp_eth_set_default_handlers(void *esp_netif)
{
esp_err_t ret;
if (!esp_netif) {
ESP_LOGE(TAG, "esp-netif handle can't be null");
return ESP_ERR_INVALID_ARG;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
return ESP_OK;
fail:
esp_eth_clear_default_handlers(esp_netif);
return ret;
}

View file

@ -276,9 +276,7 @@ err:
static esp_err_t dm9051_del(esp_eth_phy_t *phy)
{
phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent);
if (atomic_fetch_sub(&phy->ref_count, 1) == 1) {
free(dm9051);
}
free(dm9051);
return ESP_OK;
}
@ -335,8 +333,6 @@ esp_eth_phy_t *esp_eth_phy_new_dm9051(const eth_phy_config_t *config)
dm9051->parent.get_addr = dm9051_get_addr;
dm9051->parent.set_addr = dm9051_set_addr;
dm9051->parent.del = dm9051_del;
atomic_init(&dm9051->parent.ref_count, 1);
return &(dm9051->parent);
err:
return NULL;

View file

@ -274,9 +274,7 @@ err:
static esp_err_t dp83848_del(esp_eth_phy_t *phy)
{
phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent);
if (atomic_fetch_sub(&phy->ref_count, 1) == 1) {
free(dp83848);
}
free(dp83848);
return ESP_OK;
}
@ -332,7 +330,6 @@ esp_eth_phy_t *esp_eth_phy_new_dp83848(const eth_phy_config_t *config)
dp83848->parent.get_addr = dp83848_get_addr;
dp83848->parent.set_addr = dp83848_set_addr;
dp83848->parent.del = dp83848_del;
atomic_init(&dp83848->parent.ref_count, 1);
return &(dp83848->parent);
err:

View file

@ -311,9 +311,7 @@ err:
static esp_err_t ip101_del(esp_eth_phy_t *phy)
{
phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent);
if (atomic_fetch_sub(&phy->ref_count, 1) == 1) {
free(ip101);
}
free(ip101);
return ESP_OK;
}
@ -366,7 +364,6 @@ esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config)
ip101->parent.get_addr = ip101_get_addr;
ip101->parent.set_addr = ip101_set_addr;
ip101->parent.del = ip101_del;
atomic_init(&ip101->parent.ref_count, 1);
return &(ip101->parent);
err:

View file

@ -355,9 +355,7 @@ err:
static esp_err_t lan8720_del(esp_eth_phy_t *phy)
{
phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
if (atomic_fetch_sub(&phy->ref_count, 1) == 1) {
free(lan8720);
}
free(lan8720);
return ESP_OK;
}
@ -412,7 +410,6 @@ esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config)
lan8720->parent.get_addr = lan8720_get_addr;
lan8720->parent.set_addr = lan8720_set_addr;
lan8720->parent.del = lan8720_del;
atomic_init(&lan8720->parent.ref_count, 1);
return &(lan8720->parent);
err:

View file

@ -262,9 +262,7 @@ err:
static esp_err_t rtl8201_del(esp_eth_phy_t *phy)
{
phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent);
if (atomic_fetch_sub(&phy->ref_count, 1) == 1) {
free(rtl8201);
}
free(rtl8201);
return ESP_OK;
}
@ -320,7 +318,6 @@ esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config)
rtl8201->parent.get_addr = rtl8201_get_addr;
rtl8201->parent.set_addr = rtl8201_set_addr;
rtl8201->parent.del = rtl8201_del;
atomic_init(&rtl8201->parent.ref_count, 1);
return &(rtl8201->parent);
err:

View file

@ -0,0 +1,130 @@
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "test_utils.h"
#include "esp_event.h"
#include "esp_eth.h"
#include "esp_log.h"
#include "driver/gpio.h"
static const char *TAG = "dm9051_test";
#define ETH_START_BIT BIT(0)
#define ETH_STOP_BIT BIT(1)
#define ETH_CONNECT_BIT BIT(2)
#define ETH_GOT_IP_BIT BIT(3)
#define ETH_START_TIMEOUT_MS (10000)
#define ETH_CONNECT_TIMEOUT_MS (40000)
#define ETH_STOP_TIMEOUT_MS (10000)
#define ETH_GET_IP_TIMEOUT_MS (60000)
/** Event handler for Ethernet events */
static void eth_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
xEventGroupSetBits(eth_event_group, ETH_CONNECT_BIT);
ESP_LOGI(TAG, "Ethernet Link Up");
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
break;
case ETHERNET_EVENT_START:
xEventGroupSetBits(eth_event_group, ETH_START_BIT);
ESP_LOGI(TAG, "Ethernet Started");
break;
case ETHERNET_EVENT_STOP:
xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}
/** Event handler for IP_EVENT_ETH_GOT_IP */
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
const esp_netif_ip_info_t *ip_info = &event->ip_info;
ESP_LOGI(TAG, "Ethernet Got IP Address");
ESP_LOGI(TAG, "~~~~~~~~~~~");
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
ESP_LOGI(TAG, "~~~~~~~~~~~");
xEventGroupSetBits(eth_event_group, ETH_GOT_IP_BIT);
}
#if CONFIG_ETH_USE_SPI_ETHERNET
TEST_CASE("dm9051 io test", "[ethernet][dm9051][ignore]")
{
spi_device_handle_t spi_handle = NULL;
spi_bus_config_t buscfg = {
.miso_io_num = 25,
.mosi_io_num = 23,
.sclk_io_num = 19,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
TEST_ESP_OK(spi_bus_initialize(HSPI_HOST, &buscfg, 1));
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = 20 * 1000 * 1000,
.spics_io_num = 22,
.queue_size = 20
};
TEST_ESP_OK(spi_bus_add_device(HSPI_HOST, &devcfg, &spi_handle));
gpio_install_isr_service(0);
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
// create TCP/IP netif
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
// set default handlers to do layer 3 (and up) stuffs
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
// register user defined event handers
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
// install Ethernet driver
TEST_ESP_OK(esp_eth_driver_install(&config, &eth_handle));
// combine driver with netif
void *glue = esp_eth_new_netif_glue(eth_handle);
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
// start Ethernet driver
TEST_ESP_OK(esp_eth_start(eth_handle));
/* wait for IP lease */
vTaskDelay(pdMS_TO_TICKS(portMAX_DELAY));
// stop Ethernet driver
TEST_ESP_OK(esp_eth_stop(eth_handle));
TEST_ESP_OK(esp_eth_del_netif_glue(glue));
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
TEST_ESP_OK(esp_eth_clear_default_handlers(eth_netif));
esp_netif_destroy(eth_netif);
TEST_ESP_OK(esp_event_loop_delete_default());
TEST_ESP_OK(spi_bus_remove_device(spi_handle));
TEST_ESP_OK(spi_bus_free(HSPI_HOST));
}
#endif

View file

@ -1,6 +1,5 @@
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
@ -9,16 +8,12 @@
#include "esp_event.h"
#include "esp_eth.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "lwip/inet.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "ping/ping_sock.h"
#define GOT_IP_BIT BIT(0)
#define ETHERNET_GET_IP_TIMEOUT_MS (20000)
static const char *TAG = "esp_eth_test";
static const char *TAG = "esp32_eth_test";
#define ETH_START_BIT BIT(0)
#define ETH_STOP_BIT BIT(1)
@ -115,9 +110,25 @@ static void test_on_ping_end(esp_ping_handle_t hdl, void *args)
}
}
static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_wait)
{
int i = 0;
ms_to_wait += 100;
for (i = 0; i < ms_to_wait / 100; i++) {
vTaskDelay(pdMS_TO_TICKS(100));
if (esp_eth_driver_uninstall(eth_hdl) == ESP_OK) {
break;
}
}
if (i < ms_to_wait / 10) {
return ESP_OK;
} else {
return ESP_FAIL;
}
}
TEST_CASE("esp32 ethernet io test", "[ethernet][test_env=UT_T2_Ethernet]")
{
TEST_ESP_OK(esp_event_loop_create_default());
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
@ -125,7 +136,6 @@ TEST_CASE("esp32 ethernet io test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
vTaskDelay(pdMS_TO_TICKS(1000));
/* get MAC address */
uint8_t mac_addr[6];
memset(mac_addr, 0, sizeof(mac_addr));
@ -141,7 +151,6 @@ TEST_CASE("esp32 ethernet io test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_loop_delete_default());
}
TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
@ -150,8 +159,6 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
EventGroupHandle_t eth_event_group = xEventGroupCreate();
TEST_ASSERT(eth_event_group != NULL);
TEST_ESP_OK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
@ -160,23 +167,26 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
// this test only test layer2 event, so don't need to register input callback (i.e. esp_eth_update_input_path)
TEST_ESP_OK(esp_eth_start(eth_handle));
/* wait for connection start */
bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
/* wait for connection establish */
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
// stop Ethernet driver
TEST_ESP_OK(esp_eth_stop(eth_handle));
/* wait for connection stop */
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
/* driver should be uninstalled within 2 seconds */
TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
@ -186,10 +196,12 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ASSERT(eth_event_group != NULL);
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
// create TCP/IP netif
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
// set default handlers to do layer 3 (and up) stuffs
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
// register user defined event handers
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -198,24 +210,32 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
// install Ethernet driver
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
// combine driver with netif
void *glue = esp_eth_new_netif_glue(eth_handle);
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
// start Ethernet driver
TEST_ESP_OK(esp_eth_start(eth_handle));
/* wait for IP lease */
bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
// stop Ethernet driver
TEST_ESP_OK(esp_eth_stop(eth_handle));
/* wait for connection stop */
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
TEST_ESP_OK(esp_eth_del_netif_glue(glue));
/* driver should be uninstalled within 2 seconds */
TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
TEST_ESP_OK(esp_eth_clear_default_handlers(eth_netif));
esp_netif_destroy(eth_netif);
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
@ -225,10 +245,12 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ASSERT(eth_event_group != NULL);
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
// create TCP/IP netif
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
// set default handlers to do layer 3 (and up) stuffs
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
// register user defined event handers
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -238,7 +260,11 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
// combine driver with netif
void *glue = esp_eth_new_netif_glue(eth_handle);
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
// start Ethernet driver
TEST_ESP_OK(esp_eth_start(eth_handle));
/* wait for IP lease */
bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
@ -251,7 +277,7 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
memset(&target_addr, 0, sizeof(target_addr));
/* convert URL to IP */
TEST_ASSERT(getaddrinfo("www.baidu.com", NULL, &hint, &res) == 0);
struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
struct in_addr addr4 = ((struct sockaddr_in *)(res->ai_addr))->sin_addr;
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
freeaddrinfo(res);
@ -285,63 +311,19 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
/* de-initialize ping process */
TEST_ESP_OK(esp_ping_delete_session(ping));
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
// stop Ethernet driver
TEST_ESP_OK(esp_eth_stop(eth_handle));
/* wait for connection stop */
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
TEST_ESP_OK(esp_eth_del_netif_glue(glue));
/* driver should be uninstalled within 2 seconds */
TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
TEST_ESP_OK(esp_eth_clear_default_handlers(eth_netif));
esp_netif_destroy(eth_netif);
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
#if CONFIG_ETH_USE_SPI_ETHERNET
TEST_CASE("dm9051 io test", "[ethernet][ignore]")
{
spi_device_handle_t spi_handle = NULL;
spi_bus_config_t buscfg = {
.miso_io_num = 25,
.mosi_io_num = 23,
.sclk_io_num = 19,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
TEST_ESP_OK(spi_bus_initialize(HSPI_HOST, &buscfg, 1));
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = 20 * 1000 * 1000,
.spics_io_num = 22,
.queue_size = 20
};
TEST_ESP_OK(spi_bus_add_device(HSPI_HOST, &devcfg, &spi_handle));
gpio_install_isr_service(0);
esp_netif_init();
TEST_ESP_OK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
vTaskDelay(pdMS_TO_TICKS(portMAX_DELAY));
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_loop_delete_default());
TEST_ESP_OK(spi_bus_remove_device(spi_handle));
TEST_ESP_OK(spi_bus_free(HSPI_HOST));
}
#endif

View file

@ -16,12 +16,16 @@
#define _ESP_NETIF_H_
#include <stdint.h>
#include "esp_wifi_types.h"
#include "sdkconfig.h"
#include "esp_wifi_types.h"
#include "esp_netif_ip_addr.h"
#include "esp_netif_types.h"
#include "esp_netif_defaults.h"
#if CONFIG_ETH_ENABLED
#include "esp_eth_netif_glue.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -106,15 +106,9 @@ void tcpip_adapter_init(void)
}
#if CONFIG_ETH_ENABLED
static void tcpip_adapter_attach_eth_to_netif(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
esp_eth_handle_t eth_handle = *(esp_eth_handle_t*)data;
esp_netif_attach(esp_netif, eth_handle);
}
esp_err_t tcpip_adapter_clear_default_eth_handlers(void)
{
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, tcpip_adapter_attach_eth_to_netif));
return esp_eth_clear_default_handlers(netif_from_if(TCPIP_ADAPTER_IF_ETH));
}
@ -125,18 +119,25 @@ esp_err_t tcpip_adapter_set_default_eth_handlers(void)
esp_netif_t *eth_netif = esp_netif_new(&cfg);
s_esp_netifs[TCPIP_ADAPTER_IF_ETH] = eth_netif;
// provide a separate "after driver start" hook to attach
esp_err_t ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, tcpip_adapter_attach_eth_to_netif, eth_netif);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to register ");
return ret;
}
return esp_eth_set_default_handlers(eth_netif);
}
return ESP_OK;
}
esp_err_t tcpip_adapter_compat_start_eth(void *eth_driver)
{
if (s_tcpip_adapter_compat) {
esp_netif_t *esp_netif = netif_from_if(TCPIP_ADAPTER_IF_ETH);
if (esp_netif) {
esp_netif_attach(esp_netif, esp_eth_new_netif_glue(eth_driver));
}
esp_eth_start(eth_driver);
}
return ESP_OK;
}
#endif
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
@ -154,15 +155,6 @@ esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb)
return esp_netif_receive(netif_from_if(TCPIP_ADAPTER_IF_AP), buffer, len, eb);
}
esp_err_t tcpip_adapter_compat_start_eth(void* eth_driver)
{
if (s_tcpip_adapter_compat) {
esp_netif_t *esp_netif = netif_from_if(TCPIP_ADAPTER_IF_ETH);
esp_netif_attach(esp_netif, eth_driver);
}
return ESP_OK;
}
esp_err_t tcpip_adapter_set_default_wifi_handlers(void)
{
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
@ -382,4 +374,4 @@ esp_err_t tcpip_adapter_compat_start_eth(void* eth_driver)
return ESP_OK;
}
#endif
#endif

View file

@ -80,6 +80,7 @@ INPUT = \
../../components/esp_eth/include/esp_eth_com.h \
../../components/esp_eth/include/esp_eth_mac.h \
../../components/esp_eth/include/esp_eth_phy.h \
../../components/esp_eth/include/esp_eth_netif_glue.h \
##
## Peripherals - API Reference
##

View file

@ -51,3 +51,8 @@ API Reference - PHY Interface
-----------------------------
.. include:: /_build/inc/esp_eth_phy.inc
API Reference - Glue for esp_netif
----------------------------------
.. include:: /_build/inc/esp_eth_netif_glue.inc

View file

@ -134,7 +134,7 @@ static void start(void)
esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t* netif = esp_netif_new(&netif_config);
esp_netif_t *netif = esp_netif_new(&netif_config);
assert(netif);
@ -212,15 +212,12 @@ static esp_eth_phy_t *s_phy = NULL;
static void start(void)
{
esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* netif = esp_netif_new(&netif_config);
esp_netif_t *netif = esp_netif_new(&netif_config);
assert(netif);
ESP_ERROR_CHECK(esp_eth_set_default_handlers(netif));
s_example_esp_netif = netif;
// Set default handlers to process TCP/IP stuffs
ESP_ERROR_CHECK(esp_eth_set_default_handlers(netif));
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
@ -274,11 +271,12 @@ static void start(void)
s_phy = esp_eth_phy_new_dp83848(&phy_config);
#endif
// Install Ethernet driver
esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
esp_netif_attach(netif, s_eth_handle);
// combine driver with netif
esp_netif_attach(netif, esp_eth_new_netif_glue(s_eth_handle));
esp_eth_start(s_eth_handle);
s_connection_name = "Ethernet";
}

View file

@ -65,12 +65,15 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
void app_main(void)
{
// Initialize TCP/IP network interface (should be called only once in application)
esp_netif_init();
// Create default event loop that running in background
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
esp_netif_t *eth_netif = esp_netif_new(&cfg);
// Set default handlers to process TCP/IP stuffs
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
@ -120,5 +123,8 @@ void app_main(void)
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, eth_handle));
/* attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
/* start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
}

View file

@ -0,0 +1 @@
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n

View file

@ -51,7 +51,7 @@ static esp_err_t pkt_wifi2eth(void *buffer, uint16_t len, void *eb)
// Forward packets from Ethernet to Wi-Fi
// Note that, Ethernet works faster than Wi-Fi on ESP32,
// so we need to add an extra queue to balance their speed difference.
static esp_err_t pkt_eth2wifi(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t len)
static esp_err_t pkt_eth2wifi(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t len, void* priv)
{
esp_err_t ret = ESP_OK;
flow_control_msg_t msg = {
@ -190,7 +190,7 @@ static void initialize_ethernet(void)
config.stack_input = pkt_eth2wifi;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, (void *)true);
esp_eth_driver_start(s_eth_handle);
esp_eth_start(s_eth_handle);
}
static void initialize_wifi(void)

View file

@ -0,0 +1 @@
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n

View file

@ -25,7 +25,7 @@ static bool started = false;
static EventGroupHandle_t eth_event_group;
static const int GOTIP_BIT = BIT0;
static esp_eth_handle_t eth_handle = NULL;
static esp_netif_t* eth_netif = NULL;
static esp_netif_t *eth_netif = NULL;
/* "ethernet" command */
static struct {
@ -231,7 +231,8 @@ void register_ethernet(void)
#endif
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, eth_handle));
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
eth_control_args.control = arg_str1(NULL, NULL, "<info>", "Get info of Ethernet");
eth_control_args.end = arg_end(1);

View file

@ -15,3 +15,5 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# ESP32-specific
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n

View file

@ -0,0 +1 @@
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n

View file

@ -193,7 +193,7 @@ build_examples_make:
# same as above, but for CMake
.build_examples_cmake: &build_examples_cmake
extends: .build_template
parallel: 5
parallel: 8
artifacts:
when: always
paths:

View file

@ -27,3 +27,4 @@ CONFIG_EFUSE_VIRTUAL=y
CONFIG_SPIRAM_BANKSWITCH_ENABLE=n
CONFIG_FATFS_ALLOC_EXTRAM_FIRST=y
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n