forked from espressif/esp-idf
Merge branch 'feature/eth_test_all_chips' into 'master'
Ethernet related tests improvements Closes IDF-5387 See merge request espressif/esp-idf!20982
This commit is contained in:
@@ -354,6 +354,14 @@ component_ut_pytest_esp32_lan8720:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, lan8720 ]
|
||||
|
||||
component_ut_pytest_esp32_ethernet:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32
|
||||
needs:
|
||||
- build_pytest_components_esp32
|
||||
tags: [ esp32, ethernet ]
|
||||
|
||||
component_ut_pytest_esp32_flash_encryption:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
|
@@ -314,12 +314,8 @@ static esp_err_t dm9051_setup_default(emac_dm9051_t *emac)
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_RLENCR, 0x00), err, TAG, "write RLENCR failed");
|
||||
/* 3K-byte for TX and 13K-byte for RX */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MEMSCR, 0x00), err, TAG, "write MEMSCR failed");
|
||||
/* reset tx and rx memory pointer */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX), err, TAG, "write MPTRCR failed");
|
||||
/* clear network status: wakeup event, tx complete */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END), err, TAG, "write NSR failed");
|
||||
/* clear interrupt status */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS), err, TAG, "write ISR failed");
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ret;
|
||||
@@ -351,6 +347,10 @@ static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
||||
/* reset tx and rx memory pointer */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX), err, TAG, "write MPTRCR failed");
|
||||
/* clear interrupt status */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS), err, TAG, "write ISR failed");
|
||||
/* enable only Rx related interrupts as others are processed synchronously */
|
||||
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_IMR, IMR_PAR | IMR_PRI), err, TAG, "write IMR failed");
|
||||
/* enable rx */
|
||||
|
@@ -1,5 +0,0 @@
|
||||
idf_component_register(SRC_DIRS .
|
||||
PRIV_INCLUDE_DIRS .
|
||||
PRIV_REQUIRES cmock test_utils esp_eth esp_http_client esp_netif
|
||||
EMBED_TXTFILES dl_espressif_com_root_cert.pem)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
@@ -1,6 +1,8 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp_eth_test)
|
||||
|
||||
|
@@ -2,10 +2,8 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
|
||||
This test app is used to test MAC layer behavior with different PHY chips:
|
||||
This test app is used to test Ethernet MAC behavior with different chips.
|
||||
|
||||
- IP101
|
||||
- LAN8720
|
||||
|
||||
## Prerequisites
|
||||
Install third part Python packages:
|
||||
|
@@ -1,5 +1,10 @@
|
||||
idf_component_register(SRCS "esp_eth_test.c"
|
||||
idf_component_register(SRCS "esp_eth_test_apps.c"
|
||||
"esp_eth_test_l2.c"
|
||||
"esp_eth_test_hal.c"
|
||||
"esp_eth_test_common.c"
|
||||
"esp_eth_test_main.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity esp_eth esp_netif)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
PRIV_REQUIRES unity test_utils esp_eth esp_netif esp_http_client
|
||||
EMBED_TXTFILES dl_espressif_com_root_cert.pem
|
||||
WHOLE_ARCHIVE)
|
||||
|
@@ -1,14 +1,70 @@
|
||||
menu "esp_eth TEST_APPS Configuration"
|
||||
|
||||
choice TARGET_ETH_PHY_DEVICE
|
||||
choice TARGET_ETH_CONFIG
|
||||
prompt "Ethernet peripheral device"
|
||||
default TARGET_ETH_PHY_DEVICE_IP101
|
||||
default TARGET_USE_INTERNAL_ETHERNET
|
||||
help
|
||||
Select one of the devices listed here
|
||||
Select type of Ethernet interface.
|
||||
|
||||
config TARGET_USE_INTERNAL_ETHERNET
|
||||
depends on SOC_EMAC_SUPPORTED
|
||||
select ETH_USE_ESP32_EMAC
|
||||
bool "Internal EMAC"
|
||||
help
|
||||
Use internal Ethernet MAC controller.
|
||||
|
||||
config TARGET_USE_SPI_ETHERNET
|
||||
bool "SPI Ethernet"
|
||||
select ETH_USE_SPI_ETHERNET
|
||||
help
|
||||
Use external SPI-Ethernet module(s).
|
||||
endchoice # TARGET_ETH_CONFIG
|
||||
|
||||
if TARGET_USE_INTERNAL_ETHERNET
|
||||
choice TARGET_ETH_PHY_DEVICE
|
||||
prompt "Ethernet PHY"
|
||||
default TARGET_ETH_PHY_DEVICE_IP101
|
||||
help
|
||||
Select one of the devices listed here
|
||||
|
||||
config TARGET_ETH_PHY_DEVICE_IP101
|
||||
bool "IP101"
|
||||
config TARGET_ETH_PHY_DEVICE_LAN87XX
|
||||
bool "LAN8720"
|
||||
config TARGET_ETH_PHY_DEVICE_KSZ80XX
|
||||
bool "KSZ80xx"
|
||||
config TARGET_ETH_PHY_DEVICE_RTL8201
|
||||
bool "RTL8201"
|
||||
config TARGET_ETH_PHY_DEVICE_DP83848
|
||||
bool "DP83848"
|
||||
endchoice # TARGET_ETH_PHY_DEVICE
|
||||
endif # TARGET_USE_INTERNAL_ETHERNET
|
||||
|
||||
if TARGET_USE_SPI_ETHERNET
|
||||
choice TARGET_ETH_SPI_DEVICE
|
||||
prompt "Ethernet SPI Module"
|
||||
default TARGET_ETH_PHY_DEVICE_W5500
|
||||
help
|
||||
Select one of the devices listed here
|
||||
|
||||
config TARGET_ETH_PHY_DEVICE_W5500
|
||||
bool "W5500"
|
||||
select ETH_SPI_ETHERNET_W5500
|
||||
config TARGET_ETH_PHY_DEVICE_KSZ8851SNL
|
||||
bool "KSZ8851SNL"
|
||||
select ETH_SPI_ETHERNET_KSZ8851SNL
|
||||
config TARGET_ETH_PHY_DEVICE_DM9051
|
||||
bool "DM9051"
|
||||
select ETH_SPI_ETHERNET_DM9051
|
||||
endchoice # TARGET_ETH_SPI_DEVICE
|
||||
|
||||
config TARGET_SPI_CLOCK_MHZ
|
||||
int "SPI clock speed (MHz)"
|
||||
range 5 80
|
||||
default 12
|
||||
help
|
||||
Set the clock speed (MHz) of SPI interface.
|
||||
|
||||
endif # TARGET_USE_SPI_ETHERNET
|
||||
|
||||
config TARGET_ETH_PHY_DEVICE_IP101
|
||||
bool "IP101"
|
||||
config TARGET_ETH_PHY_DEVICE_LAN87XX
|
||||
bool "LAN8720"
|
||||
endchoice
|
||||
endmenu
|
||||
|
@@ -1,408 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_event.h"
|
||||
#include "unity.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#define ETH_START_BIT BIT(0)
|
||||
#define ETH_STOP_BIT BIT(1)
|
||||
#define ETH_CONNECT_BIT BIT(2)
|
||||
|
||||
#define ETH_BROADCAST_RECV_BIT BIT(0)
|
||||
#define ETH_MULTICAST_RECV_BIT BIT(1)
|
||||
#define ETH_UNICAST_RECV_BIT BIT(2)
|
||||
|
||||
#define POKE_REQ 0xFA
|
||||
#define POKE_RESP 0xFB
|
||||
#define DUMMY_TRAFFIC 0xFF
|
||||
|
||||
typedef struct {
|
||||
uint8_t dest[6];
|
||||
uint8_t src[6];
|
||||
uint16_t proto;
|
||||
uint8_t data[];
|
||||
} __attribute__((__packed__)) emac_frame_t;
|
||||
|
||||
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);
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
xEventGroupSetBits(eth_event_group, ETH_START_BIT);
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("start_and_stop", "[esp_eth]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default MAC configuration
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
#if defined(CONFIG_TARGET_ETH_PHY_DEVICE_IP101)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance
|
||||
#elif defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#endif
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
TEST_CASE("get_set_mac", "[esp_eth]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default MAC configuration
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
#if defined(CONFIG_TARGET_ETH_PHY_DEVICE_IP101)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance
|
||||
#elif defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#endif
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
|
||||
uint8_t mac_addr[6] = {};
|
||||
TEST_ASSERT_EQUAL(ESP_OK, mac->get_addr(mac, mac_addr));
|
||||
TEST_ASSERT_BITS(0b00000011, 0b00, mac_addr[0]); // Check UL&IG, should be UI
|
||||
mac_addr[5] ^= mac_addr[4];
|
||||
TEST_ASSERT_EQUAL(ESP_OK, mac->set_addr(mac, mac_addr));
|
||||
uint8_t new_mac_addr[6] = {};
|
||||
TEST_ASSERT_EQUAL(ESP_OK, mac->get_addr(mac, new_mac_addr));
|
||||
TEST_ASSERT_EQUAL(0, memcmp(mac_addr, new_mac_addr, 6));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
TEST_CASE("ethernet_broadcast_transmit", "[esp_eth]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default MAC configuration
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
#if defined(CONFIG_TARGET_ETH_PHY_DEVICE_IP101)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance
|
||||
#elif defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#endif
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// even if PHY (IP101) indicates autonegotiation done and link up, it sometimes may miss few packets after atonego reset, hence wait a bit
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
emac_frame_t *pkt = malloc(1024);
|
||||
pkt->proto = 0x2222;
|
||||
memset(pkt->dest, 0xff, 6); // broadcast addr
|
||||
for (int i = 0; i < (1024 - ETH_HEADER_LEN); ++i){
|
||||
pkt->data[i] = i & 0xff;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_transmit(eth_handle, pkt, 1024));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
free(pkt);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
static uint8_t local_mac_addr[6] = {};
|
||||
|
||||
esp_err_t l2_packet_txrx_test_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv) {
|
||||
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)priv;
|
||||
emac_frame_t *pkt = (emac_frame_t *) buffer;
|
||||
// check header
|
||||
if (pkt->proto == 0x2222 && length == 1024) {
|
||||
// check content
|
||||
for (int i = 0; i < (length - ETH_HEADER_LEN); ++i) {
|
||||
if (pkt->data[i] != (i & 0xff)) {
|
||||
printf("payload mismatch\n");
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
if (memcmp(pkt->dest, "\xff\xff\xff\xff\xff\xff", 6) == 0) {
|
||||
printf("broadcast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_BROADCAST_RECV_BIT);
|
||||
} else if (pkt->dest[0] & 0x1) {
|
||||
printf("multicast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_MULTICAST_RECV_BIT);
|
||||
} else if (memcmp(pkt->dest, local_mac_addr, 6) == 0) {
|
||||
printf("unicast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_UNICAST_RECV_BIT);
|
||||
}
|
||||
} else {
|
||||
printf("unexpected frame (protocol: 0x%x, length: %u)\n", pkt->proto, length);
|
||||
}
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
TEST_CASE("recv_pkt", "[esp_eth]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default MAC configuration
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
#if defined(CONFIG_TARGET_ETH_PHY_DEVICE_IP101)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance
|
||||
#elif defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#endif
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, mac->get_addr(mac, local_mac_addr));
|
||||
// test app will parse the DUT MAC from this line of log output
|
||||
printf("DUT MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", local_mac_addr[0], local_mac_addr[1], local_mac_addr[2],
|
||||
local_mac_addr[3], local_mac_addr[4], local_mac_addr[5]);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_update_input_path(eth_handle, l2_packet_txrx_test_cb, eth_event_group));
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT,
|
||||
true, true, pdMS_TO_TICKS(5000));
|
||||
TEST_ASSERT((bits & (ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT)) ==
|
||||
(ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SemaphoreHandle_t mutex;
|
||||
int rx_pkt_cnt;
|
||||
} recv_info_t;
|
||||
|
||||
static esp_err_t eth_recv_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv)
|
||||
{
|
||||
emac_frame_t *pkt = (emac_frame_t *)buffer;
|
||||
recv_info_t *recv_info = (recv_info_t *)priv;
|
||||
|
||||
if (pkt->proto == 0x2222) {
|
||||
switch (pkt->data[0])
|
||||
{
|
||||
case POKE_RESP:
|
||||
xSemaphoreGive(recv_info->mutex);
|
||||
break;
|
||||
|
||||
case DUMMY_TRAFFIC:
|
||||
(recv_info->rx_pkt_cnt)++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("start_stop_stress_test", "[esp_eth]")
|
||||
{
|
||||
recv_info_t recv_info;
|
||||
recv_info.mutex = xSemaphoreCreateBinary();
|
||||
TEST_ASSERT_NOT_NULL(recv_info.mutex);
|
||||
recv_info.rx_pkt_cnt = 0;
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default MAC configuration
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
#if defined(CONFIG_TARGET_ETH_PHY_DEVICE_IP101)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance
|
||||
#elif defined(CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX)
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#endif
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, mac->get_addr(mac, local_mac_addr));
|
||||
// test app will parse the DUT MAC from this line of log output
|
||||
printf("DUT MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", local_mac_addr[0], local_mac_addr[1], local_mac_addr[2],
|
||||
local_mac_addr[3], local_mac_addr[4], local_mac_addr[5]);
|
||||
|
||||
TEST_ESP_OK(esp_eth_update_input_path(eth_handle, eth_recv_cb, &recv_info));
|
||||
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
|
||||
// create a control frame to control test flow between the UT and the Python test script
|
||||
emac_frame_t *ctrl_pkt = calloc(1, 60);
|
||||
ctrl_pkt->proto = 0x2222;
|
||||
memset(ctrl_pkt->dest, 0xff, 6); // broadcast addr
|
||||
memcpy(ctrl_pkt->src, local_mac_addr, 6);
|
||||
|
||||
// create dummy data packet used for traffic generation
|
||||
emac_frame_t *pkt = calloc(1, 1500);
|
||||
pkt->proto = 0x2222;
|
||||
// we don't care about dest MAC address much, however it is better to not be broadcast or multifcast to not flood
|
||||
// other network nodes
|
||||
memset(pkt->dest, 0xBA, 6);
|
||||
memcpy(pkt->src, local_mac_addr, 6);
|
||||
|
||||
printf("EMAC start/stop stress test under heavy Tx traffic\n");
|
||||
for (int tx_i = 0; tx_i < 10; tx_i++) {
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// even if PHY (IP101) indicates autonegotiation done and link up, it sometimes may miss few packets after atonego reset, hence wait a bit
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
// at first, check that Tx/Rx path works as expected by poking the test script
|
||||
// this also serves as main PASS/FAIL criteria
|
||||
ctrl_pkt->data[0] = POKE_REQ;
|
||||
ctrl_pkt->data[1] = tx_i;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_transmit(eth_handle, ctrl_pkt, 60));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(3000)));
|
||||
printf("Tx Test iteration %d\n", tx_i);
|
||||
|
||||
// generate heavy Tx traffic
|
||||
printf("Note: transmit errors are expected...\n");
|
||||
for (int j = 0; j < 150; j++) {
|
||||
// return value is not checked on purpose since it is expected that it may fail time to time because
|
||||
// we may try to queue more packets than hardware is able to handle
|
||||
pkt->data[0] = j & 0xFF;
|
||||
esp_eth_transmit(eth_handle, pkt, 1500);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
|
||||
printf("Ethernet stopped\n");
|
||||
}
|
||||
|
||||
printf("EMAC start/stop stress test under heavy Rx traffic\n");
|
||||
for (int rx_i = 0; rx_i < 10; rx_i++) {
|
||||
recv_info.rx_pkt_cnt = 0;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// even if PHY (IP101) indicates autonegotiation done and link up, it sometimes may miss few packets after atonego reset, hence wait a bit
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
ctrl_pkt->data[0] = POKE_REQ;
|
||||
ctrl_pkt->data[1] = rx_i;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_transmit(eth_handle, ctrl_pkt, 60));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(3000)));
|
||||
printf("Rx Test iteration %d\n", rx_i);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_stop(eth_handle));
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
|
||||
printf("Recv packets: %d\n", recv_info.rx_pkt_cnt);
|
||||
TEST_ASSERT_GREATER_THAN_INT32(0, recv_info.rx_pkt_cnt);
|
||||
printf("Ethernet stopped\n");
|
||||
}
|
||||
|
||||
free(ctrl_pkt);
|
||||
free(pkt);
|
||||
|
||||
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default());
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
vEventGroupDelete(eth_event_group);
|
||||
vSemaphoreDelete(recv_info.mutex);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
@@ -5,34 +5,17 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.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_netif.h"
|
||||
#include "esp_eth.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_rom_md5.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_EMAC_SUPPORTED
|
||||
#include "esp_eth_test_common.h"
|
||||
|
||||
static const char *TAG = "esp32_eth_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)
|
||||
#define ETH_DOWNLOAD_END_TIMEOUT_MS (240000)
|
||||
|
||||
extern const char dl_espressif_com_root_cert_pem_start[] asm("_binary_dl_espressif_com_root_cert_pem_start");
|
||||
extern const char dl_espressif_com_root_cert_pem_end[] asm("_binary_dl_espressif_com_root_cert_pem_end");
|
||||
|
||||
@@ -40,48 +23,6 @@ extern const char dl_espressif_com_root_cert_pem_end[] asm("_binary_dl_espress
|
||||
static md5_context_t md5_context;
|
||||
static uint8_t digest[16];
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_wait)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -99,37 +40,59 @@ static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet io test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("ethernet io test", "[ethernet]")
|
||||
{
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
// auto detect PHY address
|
||||
phy_config.phy_addr = ESP_ETH_PHY_ADDR_AUTO;
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
/* get MAC address */
|
||||
uint8_t mac_addr[6];
|
||||
extra_eth_config(eth_handle);
|
||||
|
||||
/* get default MAC address */
|
||||
uint8_t mac_addr[ETH_ADDR_LEN];
|
||||
memset(mac_addr, 0, sizeof(mac_addr));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr));
|
||||
ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
TEST_ASSERT(mac_addr[0] != 0);
|
||||
// *** SPI Ethernet modules deviation ***
|
||||
// Rationale: The SPI Ethernet modules don't have a burned default factory MAC address hence local MAC is used
|
||||
#if !CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
TEST_ASSERT_BITS(0b00000011, 0b00, mac_addr[0]); // Check UL&IG, should be UI
|
||||
#endif
|
||||
|
||||
/* set different MAC address */
|
||||
mac_addr[5] ^= mac_addr[4];
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr));
|
||||
/* get new MAC address */
|
||||
uint8_t mac_addr_new[ETH_ADDR_LEN] = { 0 };
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr_new));
|
||||
ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr_new[0], mac_addr_new[1], mac_addr_new[2], mac_addr_new[3], mac_addr_new[4], mac_addr_new[5]);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(mac_addr_new, mac_addr, ETH_ADDR_LEN);
|
||||
|
||||
// *** SPI Ethernet modules deviation ***
|
||||
// Rationale: SPI Ethernet modules PHYs and MACs are statically configured at one die, hence there is no need for PHY address
|
||||
// from user's point of view
|
||||
#if !CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
/* get PHY address */
|
||||
int phy_addr = -1;
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_PHY_ADDR, &phy_addr));
|
||||
ESP_LOGI(TAG, "Ethernet PHY Address: %d", phy_addr);
|
||||
TEST_ASSERT(phy_addr >= 0 && phy_addr <= 31);
|
||||
#endif
|
||||
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
|
||||
TEST_ESP_OK(phy->del(phy));
|
||||
TEST_ESP_OK(mac->del(mac));
|
||||
extra_cleanup();
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("ethernet io speed/duplex/autonegotiation", "[ethernet]")
|
||||
{
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
@@ -138,19 +101,19 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
// auto detect PHY address
|
||||
phy_config.phy_addr = ESP_ETH_PHY_ADDR_AUTO;
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, &mac_config);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
extra_eth_config(eth_handle);
|
||||
|
||||
// Set PHY to loopback mode so we do not have to take care about link configuration of the other node.
|
||||
// The reason behind is improbable, however, if the other node was configured to e.g. 100 Mbps and we
|
||||
// tried to change the speed at ESP node to 10 Mbps, we could get into trouble to establish a link.
|
||||
// TODO: this test in this configuration may not work for all the chips (JIRA IDF-6186)
|
||||
bool loopback_en = true;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en);
|
||||
|
||||
@@ -173,13 +136,13 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
|
||||
|
||||
bool exp_autoneg_en;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ASSERT_EQUAL(true, exp_autoneg_en);
|
||||
|
||||
ESP_LOGI(TAG, "try to change autonegotiation when driver is started...");
|
||||
bool auto_nego_en = false;
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ASSERT_EQUAL(true, exp_autoneg_en);
|
||||
|
||||
ESP_LOGI(TAG, "stop the Ethernet driver and...");
|
||||
@@ -195,22 +158,22 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
// Disable autonegotiation and change speed to 10 Mbps and duplex to half
|
||||
ESP_LOGI(TAG, "disable the autonegotiation and change the speed/duplex...");
|
||||
auto_nego_en = false;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_AUTONEGO, &auto_nego_en));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ASSERT_EQUAL(false, exp_autoneg_en);
|
||||
|
||||
// set new duplex mode
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
|
||||
// set new speed
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
|
||||
// start the driver and wait for connection establish
|
||||
esp_eth_start(eth_handle);
|
||||
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_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
|
||||
@@ -219,14 +182,14 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
esp_eth_stop(eth_handle);
|
||||
ESP_LOGI(TAG, "change speed again...");
|
||||
speed = ETH_SPEED_100M;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
|
||||
// start the driver and wait for connection establish
|
||||
esp_eth_start(eth_handle);
|
||||
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_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
|
||||
|
||||
@@ -234,14 +197,14 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
esp_eth_stop(eth_handle);
|
||||
ESP_LOGI(TAG, "change duplex again...");
|
||||
duplex = ETH_DUPLEX_FULL;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
|
||||
// start the driver and wait for connection establish
|
||||
esp_eth_start(eth_handle);
|
||||
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_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
|
||||
@@ -253,8 +216,8 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_100M, exp_speed);
|
||||
@@ -265,17 +228,17 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
duplex = ETH_DUPLEX_HALF;
|
||||
|
||||
// set new duplex mode
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
|
||||
|
||||
// set new speed
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_SPEED, &speed));
|
||||
|
||||
// start the driver and wait for connection establish
|
||||
esp_eth_start(eth_handle);
|
||||
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_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_HALF, exp_duplex);
|
||||
TEST_ASSERT_EQUAL(ETH_SPEED_10M, exp_speed);
|
||||
@@ -287,11 +250,11 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
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_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_AUTONEGO, &exp_autoneg_en));
|
||||
TEST_ASSERT_EQUAL(true, exp_autoneg_en);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_DUPLEX_MODE, &exp_duplex));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &exp_speed));
|
||||
|
||||
// verify autonegotiation result (expecting the best link configuration)
|
||||
TEST_ASSERT_EQUAL(ETH_DUPLEX_FULL, exp_duplex);
|
||||
@@ -307,24 +270,25 @@ TEST_CASE("esp32 ethernet speed/duplex/autonegotiation", "[ethernet][test_env=UT
|
||||
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());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("ethernet event test", "[ethernet]")
|
||||
{
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
extra_eth_config(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 */
|
||||
@@ -344,10 +308,11 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
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());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("ethernet dhcp test", "[ethernet]")
|
||||
{
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
@@ -357,16 +322,15 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
// create TCP/IP netif
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
extra_eth_config(eth_handle);
|
||||
// combine driver with netif
|
||||
esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
|
||||
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
|
||||
@@ -392,10 +356,11 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
|
||||
esp_netif_destroy(eth_netif);
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet start/stop stress test", "[ethernet][test_env=UT_T2_Ethernet][timeout=240]")
|
||||
TEST_CASE("ethernet start/stop stress test with IP stack", "[ethernet]")
|
||||
{
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
@@ -405,16 +370,15 @@ TEST_CASE("esp32 ethernet start/stop stress test", "[ethernet][test_env=UT_T2_Et
|
||||
// create TCP/IP netif
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
extra_eth_config(eth_handle);
|
||||
// combine driver with netif
|
||||
esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
|
||||
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
|
||||
@@ -444,6 +408,7 @@ TEST_CASE("esp32 ethernet start/stop stress test", "[ethernet][test_env=UT_T2_Et
|
||||
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
|
||||
esp_netif_destroy(eth_netif);
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
@@ -494,7 +459,7 @@ static void eth_start_download(void)
|
||||
esp_rom_md5_final(digest, &md5_context);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 ethernet download test", "[ethernet][test_env=UT_T2_Ethernet][timeout=240]")
|
||||
TEST_CASE("ethernet download test", "[ethernet]")
|
||||
{
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
@@ -504,16 +469,15 @@ TEST_CASE("esp32 ethernet download test", "[ethernet][test_env=UT_T2_Ethernet][t
|
||||
// create TCP/IP netif
|
||||
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
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(ð_config, ð_handle));
|
||||
extra_eth_config(eth_handle);
|
||||
// combine driver with netif
|
||||
esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
|
||||
TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
|
||||
@@ -535,7 +499,7 @@ TEST_CASE("esp32 ethernet download test", "[ethernet][test_env=UT_T2_Ethernet][t
|
||||
printf("%d ", digest[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
TEST_ASSERT(memcmp(expect_digest, digest, sizeof(digest)) == 0);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(expect_digest, digest, sizeof(digest));
|
||||
|
||||
// stop Ethernet driver
|
||||
TEST_ESP_OK(esp_eth_stop(eth_handle));
|
||||
@@ -551,7 +515,6 @@ TEST_CASE("esp32 ethernet download test", "[ethernet][test_env=UT_T2_Ethernet][t
|
||||
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
|
||||
esp_netif_destroy(eth_netif);
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
#endif // SOC_EMAC_SUPPORTED
|
173
components/esp_eth/test_apps/main/esp_eth_test_common.c
Normal file
173
components/esp_eth/test_apps/main/esp_eth_test_common.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#if CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_mac.h"
|
||||
#endif // CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_eth_test_common.h"
|
||||
|
||||
#if CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
#define DEFAULT_TARGET_SPI_HOST 1
|
||||
#define DEFAULT_TARGET_SPI_MISO_GPIO 12
|
||||
#define DEFAULT_TARGET_SPI_MOSI_GPIO 13
|
||||
#define DEFAULT_TARGET_SPI_SCLK_GPIO 14
|
||||
#define DEFAULT_TARGET_SPI_CS_GPIO 15
|
||||
#endif // CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
|
||||
static const char *TAG = "esp32_eth_test_common";
|
||||
|
||||
esp_eth_mac_t *mac_init(void *vendor_emac_config, eth_mac_config_t *mac_config)
|
||||
{
|
||||
esp_eth_mac_t *mac = NULL;
|
||||
|
||||
eth_mac_config_t mac_config_default = ETH_MAC_DEFAULT_CONFIG();
|
||||
if (mac_config == NULL) {
|
||||
mac_config = &mac_config_default;
|
||||
}
|
||||
#if CONFIG_TARGET_USE_INTERNAL_ETHERNET
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
if (vendor_emac_config == NULL) {
|
||||
vendor_emac_config = &esp32_emac_config;
|
||||
}
|
||||
mac = esp_eth_mac_new_esp32(vendor_emac_config, mac_config);
|
||||
#elif CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
// Install GPIO ISR handler to be able to service SPI Eth modlues interrupts
|
||||
gpio_install_isr_service(0);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = DEFAULT_TARGET_SPI_MISO_GPIO,
|
||||
.mosi_io_num = DEFAULT_TARGET_SPI_MOSI_GPIO,
|
||||
.sclk_io_num = DEFAULT_TARGET_SPI_SCLK_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
};
|
||||
TEST_ESP_OK(spi_bus_initialize(DEFAULT_TARGET_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.mode = 0,
|
||||
.spics_io_num = DEFAULT_TARGET_SPI_CS_GPIO,
|
||||
.clock_speed_hz = CONFIG_TARGET_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||
.queue_size = 20
|
||||
};
|
||||
#if CONFIG_TARGET_ETH_PHY_DEVICE_W5500
|
||||
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(DEFAULT_TARGET_SPI_HOST, &devcfg);
|
||||
if (vendor_emac_config == NULL) {
|
||||
vendor_emac_config = &w5500_config;
|
||||
}
|
||||
mac = esp_eth_mac_new_w5500(vendor_emac_config, mac_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_KSZ8851SNL
|
||||
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(DEFAULT_TARGET_SPI_HOST, &devcfg);
|
||||
ksz8851snl_config.int_gpio_num = 4;
|
||||
if (vendor_emac_config == NULL) {
|
||||
vendor_emac_config = &ksz8851snl_config;
|
||||
}
|
||||
mac = esp_eth_mac_new_ksz8851snl(vendor_emac_config, mac_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_DM9051
|
||||
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(DEFAULT_TARGET_SPI_HOST, &devcfg);
|
||||
if (vendor_emac_config == NULL) {
|
||||
vendor_emac_config = &dm9051_config ;
|
||||
}
|
||||
mac = esp_eth_mac_new_dm9051(vendor_emac_config, mac_config);
|
||||
#endif // CONFIG_TARGET_ETH_PHY_DEVICE_W5500
|
||||
#endif // CONFIG_TARGET_USE_INTERNAL_ETHERNET
|
||||
return mac;
|
||||
}
|
||||
|
||||
esp_eth_phy_t *phy_init(eth_phy_config_t *phy_config)
|
||||
{
|
||||
esp_eth_phy_t *phy = NULL;
|
||||
eth_phy_config_t phy_config_default = ETH_PHY_DEFAULT_CONFIG();
|
||||
if (phy_config == NULL) {
|
||||
phy_config = &phy_config_default;
|
||||
}
|
||||
#if CONFIG_TARGET_USE_INTERNAL_ETHERNET
|
||||
phy_config->phy_addr = ESP_ETH_PHY_ADDR_AUTO;
|
||||
#if CONFIG_TARGET_ETH_PHY_DEVICE_IP101
|
||||
phy = esp_eth_phy_new_ip101(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX
|
||||
phy = esp_eth_phy_new_lan87xx(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_KSZ80XX
|
||||
phy = esp_eth_phy_new_ksz80xx(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201
|
||||
phy = esp_eth_phy_new_rtl8201(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_DP83848
|
||||
phy = esp_eth_phy_new_dp83848(phy_config);
|
||||
#endif // CONFIG_TARGET_ETH_PHY_DEVICE_IP101
|
||||
#elif CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
phy_config->reset_gpio_num = -1;
|
||||
#if CONFIG_TARGET_ETH_PHY_DEVICE_W5500
|
||||
phy = esp_eth_phy_new_w5500(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_KSZ8851SNL
|
||||
phy = esp_eth_phy_new_ksz8851snl(phy_config);
|
||||
#elif CONFIG_TARGET_ETH_PHY_DEVICE_DM9051
|
||||
phy = esp_eth_phy_new_dm9051(phy_config);
|
||||
#endif // CONFIG_TARGET_ETH_PHY_DEVICE_W5500
|
||||
#endif // CONFIG_TARGET_USE_INTERNAL_ETHERNET
|
||||
return phy;
|
||||
}
|
||||
|
||||
void extra_eth_config(esp_eth_handle_t eth_handle)
|
||||
{
|
||||
// *** SPI Ethernet modules deviation ***
|
||||
// Rationale: The SPI Ethernet modules don't have a burned default factory MAC address
|
||||
#if CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
uint8_t base_mac_addr[ETH_ADDR_LEN];
|
||||
TEST_ESP_OK(esp_efuse_mac_get_default(base_mac_addr));
|
||||
uint8_t local_mac[ETH_ADDR_LEN];
|
||||
TEST_ESP_OK(esp_derive_local_mac(local_mac, base_mac_addr));
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, local_mac));
|
||||
#endif
|
||||
}
|
||||
|
||||
void extra_cleanup(void)
|
||||
{
|
||||
#if CONFIG_TARGET_USE_SPI_ETHERNET
|
||||
TEST_ESP_OK(spi_bus_free(DEFAULT_TARGET_SPI_HOST));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Event handler for Ethernet events */
|
||||
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);
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
xEventGroupSetBits(eth_event_group, ETH_START_BIT);
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for IP_EVENT_ETH_GOT_IP */
|
||||
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);
|
||||
}
|
42
components/esp_eth/test_apps/main/esp_eth_test_common.h
Normal file
42
components/esp_eth/test_apps/main/esp_eth_test_common.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
#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)
|
||||
#define ETH_DOWNLOAD_END_TIMEOUT_MS (240000)
|
||||
|
||||
typedef struct {
|
||||
uint8_t dest[ETH_ADDR_LEN];
|
||||
uint8_t src[ETH_ADDR_LEN];
|
||||
uint16_t proto;
|
||||
uint8_t data[];
|
||||
} __attribute__((__packed__)) emac_frame_t;
|
||||
|
||||
esp_eth_mac_t *mac_init(void *vendor_emac_config, eth_mac_config_t *mac_config);
|
||||
esp_eth_phy_t *phy_init(eth_phy_config_t *phy_config);
|
||||
void extra_eth_config(esp_eth_handle_t eth_handle);
|
||||
void extra_cleanup(void);
|
||||
|
||||
/** Event handler for Ethernet events */
|
||||
void eth_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data);
|
||||
/** Event handler for IP_EVENT_ETH_GOT_IP */
|
||||
void got_ip_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data);
|
255
components/esp_eth/test_apps/main/esp_eth_test_hal.c
Normal file
255
components/esp_eth/test_apps/main/esp_eth_test_hal.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_eth_test_common.h"
|
||||
|
||||
#define ETHERTYPE_TX_STD 0x2222 // frame transmitted via emac_hal_transmit_frame
|
||||
#define ETHERTYPE_TX_MULTI_2 0x2223 // frame transmitted via emac_hal_transmit_multiple_buf_frame (2 buffers)
|
||||
#define ETHERTYPE_TX_MULTI_3 0x2224 // frame transmitted via emac_hal_transmit_multiple_buf_frame (3 buffers)
|
||||
|
||||
static const char *TAG = "esp32_eth_test_hal";
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SemaphoreHandle_t mutex;
|
||||
uint16_t expected_size;
|
||||
uint16_t expected_size_2;
|
||||
uint16_t expected_size_3;
|
||||
} recv_hal_check_info_t;
|
||||
|
||||
static esp_err_t eth_recv_hal_check_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv)
|
||||
{
|
||||
emac_frame_t *pkt = (emac_frame_t *)buffer;
|
||||
recv_hal_check_info_t *recv_info = (recv_hal_check_info_t *)priv;
|
||||
uint16_t expected_size = recv_info->expected_size + recv_info->expected_size_2 + recv_info->expected_size_3;
|
||||
|
||||
ESP_LOGI(TAG, "recv frame size: %" PRIu16, expected_size);
|
||||
TEST_ASSERT_EQUAL(expected_size, length);
|
||||
// frame transmitted via emac_hal_transmit_frame
|
||||
if (pkt->proto == ETHERTYPE_TX_STD) {
|
||||
for (int i = 0; i < recv_info->expected_size - ETH_HEADER_LEN; i++) {
|
||||
TEST_ASSERT_EQUAL(pkt->data[i], i & 0xFF);
|
||||
}
|
||||
// frame transmitted via emac_hal_transmit_multiple_buf_frame (2 buffers)
|
||||
} else if (pkt->proto == ETHERTYPE_TX_MULTI_2) {
|
||||
uint8_t *data_p = pkt->data;
|
||||
for (int i = 0; i < recv_info->expected_size - ETH_HEADER_LEN; i++) {
|
||||
TEST_ASSERT_EQUAL(*(data_p++), i & 0xFF);
|
||||
}
|
||||
int j = ETH_MAX_PAYLOAD_LEN;
|
||||
for (int i = 0; i < recv_info->expected_size_2; i++) {
|
||||
TEST_ASSERT_EQUAL(*(data_p++), j & 0xFF);
|
||||
j--;
|
||||
}
|
||||
// frame transmitted via emac_hal_transmit_multiple_buf_frame (3 buffers)
|
||||
} else if (pkt->proto == ETHERTYPE_TX_MULTI_3) {
|
||||
uint8_t *data_p = pkt->data;
|
||||
for (int i = 0; i < recv_info->expected_size - ETH_HEADER_LEN; i++) {
|
||||
TEST_ASSERT_EQUAL(*(data_p++), i & 0xFF);
|
||||
}
|
||||
int j = ETH_MAX_PAYLOAD_LEN;
|
||||
for (int i = 0; i < recv_info->expected_size_2; i++) {
|
||||
TEST_ASSERT_EQUAL(*(data_p++), j & 0xFF);
|
||||
j--;
|
||||
}
|
||||
for (int i = 0; i < recv_info->expected_size_3; i++) {
|
||||
TEST_ASSERT_EQUAL(*(data_p++), i & 0xFF);
|
||||
}
|
||||
} else {
|
||||
TEST_FAIL();
|
||||
}
|
||||
memset(buffer, 0, length);
|
||||
free(buffer);
|
||||
xSemaphoreGive(recv_info->mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("hal receive/transmit", "[emac_hal]")
|
||||
{
|
||||
recv_hal_check_info_t recv_info;
|
||||
recv_info.mutex = xSemaphoreCreateBinary();
|
||||
TEST_ASSERT_NOT_NULL(recv_info.mutex);
|
||||
recv_info.expected_size = 0;
|
||||
recv_info.expected_size_2 = 0;
|
||||
recv_info.expected_size_3 = 0;
|
||||
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ESP_OK(esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
extra_eth_config(eth_handle);
|
||||
|
||||
// loopback greatly simplifies the test
|
||||
bool loopback_en = true;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en);
|
||||
|
||||
TEST_ESP_OK(esp_eth_update_input_path(eth_handle, eth_recv_hal_check_cb, &recv_info));
|
||||
|
||||
// start the driver
|
||||
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);
|
||||
|
||||
// create test frame
|
||||
emac_frame_t *test_pkt = calloc(1, ETH_MAX_PACKET_SIZE);
|
||||
test_pkt->proto = ETHERTYPE_TX_STD;
|
||||
memset(test_pkt->dest, 0xff, ETH_ADDR_LEN); // broadcast addr
|
||||
uint8_t local_mac_addr[ETH_ADDR_LEN] = { 0 };
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, local_mac_addr));
|
||||
memcpy(test_pkt->src, local_mac_addr, ETH_ADDR_LEN);
|
||||
// fill with data
|
||||
for (int i = 0; i < ETH_MAX_PAYLOAD_LEN; i++) {
|
||||
test_pkt->data[i] = i & 0xFF;
|
||||
}
|
||||
|
||||
// verify that HAL driver correctly processes frame from EMAC descriptors
|
||||
uint16_t transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE - 1;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE + 1;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = 2 * CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = 2 * CONFIG_ETH_DMA_BUFFER_SIZE - 1;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = 2 * CONFIG_ETH_DMA_BUFFER_SIZE + 1;
|
||||
ESP_LOGI(TAG, "transmit frame size: %" PRIu16, transmit_size);
|
||||
recv_info.expected_size = transmit_size;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
// verify transmission of multiple buffers
|
||||
uint16_t transmit_size_2;
|
||||
// allocated the second buffer
|
||||
uint8_t *pkt_data_2 = malloc(ETH_MAX_PAYLOAD_LEN);
|
||||
// fill with data (reverse order to differentiate the buffers)
|
||||
int j = ETH_MAX_PAYLOAD_LEN;
|
||||
for (int i = 0; i < ETH_MAX_PAYLOAD_LEN; i++) {
|
||||
pkt_data_2[i] = j & 0xFF;
|
||||
j--;
|
||||
}
|
||||
// change protocol number so the cb function is aware that frame was joint from two buffers
|
||||
test_pkt->proto = ETHERTYPE_TX_MULTI_2;
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
ESP_LOGI(TAG, "transmit joint frame size: %" PRIu16, transmit_size + transmit_size_2);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 2, test_pkt, transmit_size, pkt_data_2, transmit_size_2));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE - 1;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
ESP_LOGI(TAG, "transmit joint frame size: %" PRIu16, transmit_size + transmit_size_2);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 2, test_pkt, transmit_size, pkt_data_2, transmit_size_2));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE + 1;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
ESP_LOGI(TAG, "transmit joint frame size: %" PRIu16, transmit_size + transmit_size_2);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 2, test_pkt, transmit_size, pkt_data_2, transmit_size_2));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
uint16_t transmit_size_3 = 256;
|
||||
// allocated the third buffer
|
||||
uint8_t *pkt_data_3 = malloc(256);
|
||||
// fill with data
|
||||
for (int i = 0; i < 256; i++) {
|
||||
pkt_data_3[i] = i & 0xFF;
|
||||
}
|
||||
// change protocol number so the cb function is aware that frame was joint from three buffers
|
||||
test_pkt->proto = ETHERTYPE_TX_MULTI_3;
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
transmit_size_3 = 256;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
recv_info.expected_size_3 = transmit_size_3;
|
||||
ESP_LOGI(TAG, "transmit joint frame size (3 buffs): %" PRIu16, transmit_size + transmit_size_2 + transmit_size_3);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 3, test_pkt, transmit_size, pkt_data_2, transmit_size_2, pkt_data_3, transmit_size_3));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE - 1;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
transmit_size_3 = 256;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
recv_info.expected_size_3 = transmit_size_3;
|
||||
ESP_LOGI(TAG, "transmit joint frame size (3 buffs): %" PRIu16, transmit_size + transmit_size_2 + transmit_size_3);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 3, test_pkt, transmit_size, pkt_data_2, transmit_size_2, pkt_data_3, transmit_size_3));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE + 1;
|
||||
transmit_size_2 = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||
transmit_size_3 = 256;
|
||||
recv_info.expected_size = transmit_size;
|
||||
recv_info.expected_size_2 = transmit_size_2;
|
||||
recv_info.expected_size_3 = transmit_size_3;
|
||||
ESP_LOGI(TAG, "transmit joint frame size (3 buffs): %" PRIu16, transmit_size + transmit_size_2 + transmit_size_3);
|
||||
TEST_ESP_OK(esp_eth_transmit_vargs(eth_handle, 3, test_pkt, transmit_size, pkt_data_2, transmit_size_2, pkt_data_3, transmit_size_3));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(500)));
|
||||
|
||||
free(test_pkt);
|
||||
free(pkt_data_2);
|
||||
free(pkt_data_3);
|
||||
|
||||
// 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_driver_uninstall(eth_handle));
|
||||
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());
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
vSemaphoreDelete(recv_info.mutex);
|
||||
}
|
277
components/esp_eth/test_apps/main/esp_eth_test_l2.c
Normal file
277
components/esp_eth/test_apps/main/esp_eth_test_l2.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_eth_test_common.h"
|
||||
|
||||
#define ETH_BROADCAST_RECV_BIT BIT(0)
|
||||
#define ETH_MULTICAST_RECV_BIT BIT(1)
|
||||
#define ETH_UNICAST_RECV_BIT BIT(2)
|
||||
|
||||
#define POKE_REQ 0xFA
|
||||
#define POKE_RESP 0xFB
|
||||
#define DUMMY_TRAFFIC 0xFF
|
||||
|
||||
TEST_CASE("ethernet broadcast transmit", "[ethernet_l2]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ESP_OK(esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
extra_eth_config(eth_handle);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
TEST_ESP_OK(esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// if DUT is connected in network with switch: even if link is indicated up, it may take some time the switch
|
||||
// starts switching the associated port (e.g. it runs RSTP at first)
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
emac_frame_t *pkt = malloc(1024);
|
||||
pkt->proto = 0x2222;
|
||||
TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, pkt->src));
|
||||
memset(pkt->dest, 0xff, ETH_ADDR_LEN); // broadcast addr
|
||||
for (int i = 0; i < (1024 - ETH_HEADER_LEN); ++i){
|
||||
pkt->data[i] = i & 0xff;
|
||||
}
|
||||
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, pkt, 1024));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
free(pkt);
|
||||
|
||||
TEST_ESP_OK(esp_eth_stop(eth_handle));
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
static uint8_t local_mac_addr[ETH_ADDR_LEN] = {};
|
||||
|
||||
esp_err_t l2_packet_txrx_test_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv) {
|
||||
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)priv;
|
||||
emac_frame_t *pkt = (emac_frame_t *) buffer;
|
||||
// check header
|
||||
if (pkt->proto == 0x2222 && length == 1024) {
|
||||
// check content
|
||||
for (int i = 0; i < (length - ETH_HEADER_LEN); ++i) {
|
||||
if (pkt->data[i] != (i & 0xff)) {
|
||||
printf("payload mismatch\n");
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
if (memcmp(pkt->dest, "\xff\xff\xff\xff\xff\xff", ETH_ADDR_LEN) == 0) {
|
||||
printf("broadcast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_BROADCAST_RECV_BIT);
|
||||
} else if (pkt->dest[0] & 0x1) {
|
||||
printf("multicast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_MULTICAST_RECV_BIT);
|
||||
} else if (memcmp(pkt->dest, local_mac_addr, ETH_ADDR_LEN) == 0) {
|
||||
printf("unicast received...\n");
|
||||
xEventGroupSetBits(eth_event_group, ETH_UNICAST_RECV_BIT);
|
||||
}
|
||||
} else {
|
||||
printf("unexpected frame (protocol: 0x%x, length: %" PRIu32 ")\n", pkt->proto, length);
|
||||
}
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
TEST_CASE("ethernet recv_pkt", "[ethernet_l2]")
|
||||
{
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ESP_OK(esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
extra_eth_config(eth_handle);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
|
||||
TEST_ESP_OK(mac->get_addr(mac, local_mac_addr));
|
||||
// test app will parse the DUT MAC from this line of log output
|
||||
printf("DUT MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", local_mac_addr[0], local_mac_addr[1], local_mac_addr[2],
|
||||
local_mac_addr[3], local_mac_addr[4], local_mac_addr[5]);
|
||||
|
||||
TEST_ESP_OK(esp_eth_update_input_path(eth_handle, l2_packet_txrx_test_cb, eth_event_group));
|
||||
|
||||
EventBits_t bits = 0;
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT,
|
||||
true, true, pdMS_TO_TICKS(5000));
|
||||
TEST_ASSERT((bits & (ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT)) ==
|
||||
(ETH_BROADCAST_RECV_BIT | ETH_MULTICAST_RECV_BIT | ETH_UNICAST_RECV_BIT));
|
||||
|
||||
TEST_ESP_OK(esp_eth_stop(eth_handle));
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SemaphoreHandle_t mutex;
|
||||
int rx_pkt_cnt;
|
||||
} recv_info_t;
|
||||
|
||||
static esp_err_t eth_recv_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv)
|
||||
{
|
||||
emac_frame_t *pkt = (emac_frame_t *)buffer;
|
||||
recv_info_t *recv_info = (recv_info_t *)priv;
|
||||
|
||||
if (pkt->proto == 0x2222) {
|
||||
switch (pkt->data[0])
|
||||
{
|
||||
case POKE_RESP:
|
||||
xSemaphoreGive(recv_info->mutex);
|
||||
break;
|
||||
|
||||
case DUMMY_TRAFFIC:
|
||||
(recv_info->rx_pkt_cnt)++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("ethernet start/stop stress test under heavy traffic", "[ethernet_l2]")
|
||||
{
|
||||
recv_info_t recv_info;
|
||||
recv_info.mutex = xSemaphoreCreateBinary();
|
||||
TEST_ASSERT_NOT_NULL(recv_info.mutex);
|
||||
recv_info.rx_pkt_cnt = 0;
|
||||
|
||||
esp_eth_mac_t *mac = mac_init(NULL, NULL);
|
||||
TEST_ASSERT_NOT_NULL(mac);
|
||||
esp_eth_phy_t *phy = phy_init(NULL);
|
||||
TEST_ASSERT_NOT_NULL(phy);
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
TEST_ESP_OK(esp_eth_driver_install(&config, ð_handle)); // install driver
|
||||
TEST_ASSERT_NOT_NULL(eth_handle);
|
||||
extra_eth_config(eth_handle);
|
||||
|
||||
TEST_ESP_OK(mac->get_addr(mac, local_mac_addr));
|
||||
// test app will parse the DUT MAC from this line of log output
|
||||
printf("DUT MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", local_mac_addr[0], local_mac_addr[1], local_mac_addr[2],
|
||||
local_mac_addr[3], local_mac_addr[4], local_mac_addr[5]);
|
||||
|
||||
TEST_ESP_OK(esp_eth_update_input_path(eth_handle, eth_recv_cb, &recv_info));
|
||||
|
||||
EventBits_t bits = 0;
|
||||
EventGroupHandle_t eth_event_group = xEventGroupCreate();
|
||||
TEST_ASSERT(eth_event_group != NULL);
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, eth_event_group));
|
||||
|
||||
// create a control frame to control test flow between the UT and the Python test script
|
||||
emac_frame_t *ctrl_pkt = calloc(1, 60);
|
||||
ctrl_pkt->proto = 0x2222;
|
||||
memset(ctrl_pkt->dest, 0xff, ETH_ADDR_LEN); // broadcast addr
|
||||
memcpy(ctrl_pkt->src, local_mac_addr, ETH_ADDR_LEN);
|
||||
|
||||
// create dummy data packet used for traffic generation
|
||||
emac_frame_t *pkt = calloc(1, 1500);
|
||||
pkt->proto = 0x2222;
|
||||
// we don't care about dest MAC address much, however it is better to not be broadcast or multifcast to not flood
|
||||
// other network nodes
|
||||
memset(pkt->dest, 0xBA, ETH_ADDR_LEN);
|
||||
memcpy(pkt->src, local_mac_addr, ETH_ADDR_LEN);
|
||||
|
||||
printf("EMAC start/stop stress test under heavy Tx traffic\n");
|
||||
for (int tx_i = 0; tx_i < 10; tx_i++) {
|
||||
TEST_ESP_OK(esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// if DUT is connected in network with switch: even if link is indicated up, it may take some time the switch
|
||||
// starts switching the associated port (e.g. it runs RSTP at first)
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
// at first, check that Tx/Rx path works as expected by poking the test script
|
||||
// this also serves as main PASS/FAIL criteria
|
||||
ctrl_pkt->data[0] = POKE_REQ;
|
||||
ctrl_pkt->data[1] = tx_i;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, ctrl_pkt, 60));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(3000)));
|
||||
printf("Tx Test iteration %d\n", tx_i);
|
||||
|
||||
// generate heavy Tx traffic
|
||||
printf("Note: transmit errors are expected...\n");
|
||||
for (int j = 0; j < 150; j++) {
|
||||
// return value is not checked on purpose since it is expected that it may fail time to time because
|
||||
// we may try to queue more packets than hardware is able to handle
|
||||
pkt->data[0] = j & 0xFF; // sequence number
|
||||
esp_eth_transmit(eth_handle, pkt, 1500);
|
||||
}
|
||||
TEST_ESP_OK(esp_eth_stop(eth_handle));
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
|
||||
printf("Ethernet stopped\n");
|
||||
}
|
||||
|
||||
printf("EMAC start/stop stress test under heavy Rx traffic\n");
|
||||
for (int rx_i = 0; rx_i < 10; rx_i++) {
|
||||
recv_info.rx_pkt_cnt = 0;
|
||||
TEST_ESP_OK(esp_eth_start(eth_handle)); // start Ethernet driver state machine
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
|
||||
// if DUT is connected in network with switch: even if link is indicated up, it may take some time the switch
|
||||
// starts switching the associated port (e.g. it runs RSTP at first)
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
ctrl_pkt->data[0] = POKE_REQ;
|
||||
ctrl_pkt->data[1] = rx_i;
|
||||
TEST_ESP_OK(esp_eth_transmit(eth_handle, ctrl_pkt, 60));
|
||||
TEST_ASSERT(xSemaphoreTake(recv_info.mutex, pdMS_TO_TICKS(3000)));
|
||||
printf("Rx Test iteration %d\n", rx_i);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
TEST_ESP_OK(esp_eth_stop(eth_handle));
|
||||
bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(3000));
|
||||
TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
|
||||
printf("Recv packets: %d\n", recv_info.rx_pkt_cnt);
|
||||
TEST_ASSERT_GREATER_THAN_INT32(0, recv_info.rx_pkt_cnt);
|
||||
printf("Ethernet stopped\n");
|
||||
}
|
||||
|
||||
free(ctrl_pkt);
|
||||
free(pkt);
|
||||
|
||||
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
|
||||
phy->del(phy);
|
||||
mac->del(mac);
|
||||
extra_cleanup();
|
||||
vEventGroupDelete(eth_event_group);
|
||||
vSemaphoreDelete(recv_info.mutex);
|
||||
}
|
11
components/esp_eth/test_apps/main/esp_eth_test_main.c
Normal file
11
components/esp_eth/test_apps/main/esp_eth_test_main.c
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "test_utils.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
@@ -5,6 +5,7 @@ import contextlib
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
from multiprocessing import Pipe, Process, connection
|
||||
from typing import Iterator
|
||||
|
||||
@@ -16,28 +17,34 @@ ETH_TYPE = 0x2222
|
||||
|
||||
|
||||
class EthTestIntf(object):
|
||||
def __init__(self, eth_type: int):
|
||||
def __init__(self, eth_type: int, my_if: str = ''):
|
||||
self.target_if = ''
|
||||
self.eth_type = eth_type
|
||||
self.find_target_if(my_if)
|
||||
|
||||
def find_target_if(self) -> None:
|
||||
def find_target_if(self, my_if: str = '') -> None:
|
||||
# try to determine which interface to use
|
||||
netifs = os.listdir('/sys/class/net/')
|
||||
logging.info('detected interfaces: %s', str(netifs))
|
||||
|
||||
for netif in netifs:
|
||||
if netif.find('eth') == 0 or netif.find('enp') == 0 or netif.find('eno') == 0:
|
||||
self.target_if = netif
|
||||
break
|
||||
# if no interface defined, try to find it automatically
|
||||
if my_if == '':
|
||||
if netif.find('eth') == 0 or netif.find('enp') == 0 or netif.find('eno') == 0:
|
||||
self.target_if = netif
|
||||
break
|
||||
else:
|
||||
if netif.find(my_if) == 0:
|
||||
self.target_if = my_if
|
||||
break
|
||||
if self.target_if == '':
|
||||
raise Exception('no network interface found')
|
||||
raise Exception('network interface not found')
|
||||
logging.info('Use %s for testing', self.target_if)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def configure_eth_if(self) -> Iterator[socket.socket]:
|
||||
so = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(self.eth_type))
|
||||
so.bind((self.target_if, 0))
|
||||
|
||||
try:
|
||||
yield so
|
||||
finally:
|
||||
@@ -83,25 +90,34 @@ class EthTestIntf(object):
|
||||
raise e
|
||||
|
||||
|
||||
def actual_test(dut: Dut) -> None:
|
||||
target_if = EthTestIntf(ETH_TYPE)
|
||||
target_if.find_target_if()
|
||||
|
||||
def ethernet_test(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('\n')
|
||||
|
||||
dut.expect_exact('Enter test for running.')
|
||||
dut.write('"start_and_stop"')
|
||||
dut.write('[ethernet]')
|
||||
dut.expect_unity_test_output(timeout=980)
|
||||
|
||||
|
||||
def ethernet_int_emac_hal_test(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('\n')
|
||||
|
||||
dut.expect_exact('Enter test for running.')
|
||||
dut.write('[emac_hal]')
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
dut.expect_exact("Enter next test, or 'enter' to see menu")
|
||||
dut.write('"get_set_mac"')
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
dut.expect_exact("Enter next test, or 'enter' to see menu")
|
||||
def ethernet_l2_test(dut: Dut) -> None:
|
||||
target_if = EthTestIntf(ETH_TYPE)
|
||||
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('\n')
|
||||
dut.expect_exact('Enter test for running.')
|
||||
|
||||
with target_if.configure_eth_if() as so:
|
||||
so.settimeout(30)
|
||||
dut.write('"ethernet_broadcast_transmit"')
|
||||
dut.write('"ethernet broadcast transmit"')
|
||||
eth_frame = Ether(so.recv(1024))
|
||||
for i in range(0, 1010):
|
||||
if eth_frame.load[i] != i & 0xff:
|
||||
@@ -109,18 +125,19 @@ def actual_test(dut: Dut) -> None:
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
dut.expect_exact("Enter next test, or 'enter' to see menu")
|
||||
dut.write('"recv_pkt"')
|
||||
dut.write('"ethernet recv_pkt"')
|
||||
res = dut.expect(
|
||||
r'([\s\S]*)'
|
||||
r'DUT MAC: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})'
|
||||
)
|
||||
time.sleep(1)
|
||||
target_if.send_eth_packet('ff:ff:ff:ff:ff:ff') # broadcast frame
|
||||
target_if.send_eth_packet('01:00:00:00:00:00') # multicast frame
|
||||
target_if.send_eth_packet(res.group(2)) # unicast frame
|
||||
dut.expect_unity_test_output(extra_before=res.group(1))
|
||||
|
||||
dut.expect_exact("Enter next test, or 'enter' to see menu")
|
||||
dut.write('"start_stop_stress_test"')
|
||||
dut.write('"ethernet start/stop stress test under heavy traffic"')
|
||||
res = dut.expect(
|
||||
r'([\s\S]*)'
|
||||
r'DUT MAC: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})'
|
||||
@@ -144,21 +161,43 @@ def actual_test(dut: Dut) -> None:
|
||||
dut.expect_unity_test_output(extra_before=res.group(1))
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
@pytest.mark.parametrize('config', [
|
||||
'default_ip101',
|
||||
'release_ip101',
|
||||
'single_core_ip101'
|
||||
], indirect=True)
|
||||
@pytest.mark.flaky(reruns=3, reruns_delay=5)
|
||||
def test_esp_ethernet(dut: Dut) -> None:
|
||||
ethernet_test(dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
@pytest.mark.parametrize('config', [
|
||||
'default_ip101',
|
||||
], indirect=True)
|
||||
@pytest.mark.flaky(reruns=3, reruns_delay=5)
|
||||
def test_esp_emac_hal(dut: Dut) -> None:
|
||||
ethernet_int_emac_hal_test(dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ip101
|
||||
@pytest.mark.parametrize('config', [
|
||||
'ip101',
|
||||
'default_ip101',
|
||||
], indirect=True)
|
||||
@pytest.mark.flaky(reruns=3, reruns_delay=5)
|
||||
def test_esp_eth_ip101(dut: Dut) -> None:
|
||||
actual_test(dut)
|
||||
ethernet_l2_test(dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.lan8720
|
||||
@pytest.mark.parametrize('config', [
|
||||
'lan8720',
|
||||
'default_lan8720',
|
||||
], indirect=True)
|
||||
@pytest.mark.flaky(reruns=3, reruns_delay=5)
|
||||
def test_esp_eth_lan8720(dut: Dut) -> None:
|
||||
actual_test(dut)
|
||||
ethernet_l2_test(dut)
|
||||
|
8
components/esp_eth/test_apps/sdkconfig.ci.default_dm9051
Normal file
8
components/esp_eth/test_apps/sdkconfig.ci.default_dm9051
Normal file
@@ -0,0 +1,8 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_SPI_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_DM9051=y
|
@@ -0,0 +1,9 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_DP83848=y
|
@@ -1,7 +1,9 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y
|
11
components/esp_eth/test_apps/sdkconfig.ci.default_ksz80xx
Normal file
11
components/esp_eth/test_apps/sdkconfig.ci.default_ksz80xx
Normal file
@@ -0,0 +1,11 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_KSZ80XX=y
|
||||
CONFIG_ETH_RMII_CLK_OUTPUT=y
|
||||
CONFIG_ETH_RMII_CLK_OUT_GPIO=17
|
@@ -0,0 +1,8 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_SPI_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_KSZ8851SNL=y
|
@@ -1,9 +1,11 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_LAN87XX=y
|
||||
CONFIG_ETH_RMII_CLK_OUTPUT=y
|
||||
CONFIG_ETH_RMII_CLK_OUT_GPIO=17
|
@@ -0,0 +1,9 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_RTL8201=y
|
8
components/esp_eth/test_apps/sdkconfig.ci.default_w5500
Normal file
8
components/esp_eth/test_apps/sdkconfig.ci.default_w5500
Normal file
@@ -0,0 +1,8 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_SPI_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_W5500=y
|
12
components/esp_eth/test_apps/sdkconfig.ci.release_ip101
Normal file
12
components/esp_eth/test_apps/sdkconfig.ci.release_ip101
Normal file
@@ -0,0 +1,12 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y
|
13
components/esp_eth/test_apps/sdkconfig.ci.single_core_ip101
Normal file
13
components/esp_eth/test_apps/sdkconfig.ci.single_core_ip101
Normal file
@@ -0,0 +1,13 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_MEMMAP_SMP=n
|
||||
CONFIG_FREERTOS_UNICORE=y
|
||||
CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY=y
|
||||
CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y
|
||||
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
CONFIG_ETH_USE_ESP32_EMAC=y
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
|
||||
CONFIG_TARGET_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_TARGET_ETH_PHY_DEVICE_IP101=y
|
@@ -1,6 +1,6 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/esp_netif/test_apps:
|
||||
components/esp_netif/test_apps/test_app_esp_netif:
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
temporary: true
|
||||
@@ -9,3 +9,9 @@ components/esp_netif/test_apps:
|
||||
- if: IDF_TARGET != "esp32s2"
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
|
||||
components/esp_netif/test_apps/test_app_vfs_l2tap:
|
||||
disable:
|
||||
- if: SOC_EMAC_SUPPORTED != 1
|
||||
temporary: false
|
||||
reason: test uses internal EMAC
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
@@ -0,0 +1,10 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp_vfs_l2tap_test)
|
||||
|
||||
idf_component_get_property(lib esp_netif COMPONENT_LIB)
|
||||
target_compile_options(${lib} PRIVATE "-fsanitize=undefined" "-fno-sanitize=shift-base")
|
@@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock test_utils esp_netif driver esp_eth)
|
@@ -11,6 +11,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
@@ -29,8 +30,6 @@
|
||||
|
||||
#include "esp_vfs_l2tap.h"
|
||||
|
||||
#if CONFIG_ESP_NETIF_L2_TAP
|
||||
|
||||
#define ETH_FILTER_LE 0x7A05
|
||||
#define ETH_FILTER_BE 0x057A
|
||||
|
||||
@@ -240,7 +239,7 @@ static void send_task(void *task_param)
|
||||
* @brief Verifies vfs register/unregister functions
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - vfs register", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - vfs register", "[ethernet]")
|
||||
{
|
||||
int eth_tap_fd;
|
||||
|
||||
@@ -344,7 +343,7 @@ static void close_task(void *task_param)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 l2tap - open/close", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - open/close", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
|
||||
@@ -415,7 +414,7 @@ TEST_CASE("esp32 l2tap - open/close", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
* @brief Verifies that read does not block when fd is opened in non-blocking mode
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - non blocking read", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - non blocking read", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -536,7 +535,7 @@ TEST_CASE("esp32 l2tap - non blocking read", "[ethernet][test_env=UT_T2_Ethernet
|
||||
* @brief Verifies that read blocks when fd opened in blocking mode
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - blocking read", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - blocking read", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -599,7 +598,7 @@ TEST_CASE("esp32 l2tap - blocking read", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
* @brief Verifies write
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - write", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - write", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -718,12 +717,12 @@ static void multi_fds_task (void *task_param)
|
||||
for (int i = 0; i < sizeof(eth_tap_fds) / sizeof(int); i++) {
|
||||
TEST_ASSERT_EQUAL(0, close(eth_tap_fds[i]));
|
||||
}
|
||||
ESP_LOGI(TAG, "multi_fds_task %u done", task_info->task_id);
|
||||
ESP_LOGI(TAG, "multi_fds_task %" PRIu16 "done", task_info->task_id);
|
||||
xSemaphoreGive(task_info->semaphore);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("esp32 l2tap - read/write multiple fd's used by multiple tasks", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - read/write multiple fd's used by multiple tasks", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
|
||||
@@ -752,7 +751,7 @@ TEST_CASE("esp32 l2tap - read/write multiple fd's used by multiple tasks", "[eth
|
||||
* @brief Verifies proper functionality of ioctl RCV_FILTER option
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - ioctl - RCV_FILTER", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - ioctl - RCV_FILTER", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -849,7 +848,7 @@ TEST_CASE("esp32 l2tap - ioctl - RCV_FILTER", "[ethernet][test_env=UT_T2_Etherne
|
||||
* @brief Verifies proper functionality of ioctl INTF_DEVICE option
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - ioctl - INTF_DEVICE/DEVICE_DRV_HNDL", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - ioctl - INTF_DEVICE/DEVICE_DRV_HNDL", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -939,7 +938,7 @@ TEST_CASE("esp32 l2tap - ioctl - INTF_DEVICE/DEVICE_DRV_HNDL", "[ethernet][test_
|
||||
* @brief Verifies proper functionality of ioctl unknown option
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - ioctl - unknown", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - ioctl - unknown", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -964,7 +963,7 @@ TEST_CASE("esp32 l2tap - ioctl - unknown", "[ethernet][test_env=UT_T2_Ethernet]"
|
||||
* @brief Verifies proper functionality of fcntl
|
||||
*
|
||||
*/
|
||||
TEST_CASE("esp32 l2tap - fcntl", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_CASE("esp32 l2tap - fcntl", "[ethernet]")
|
||||
{
|
||||
test_vfs_eth_network_t eth_network_hndls;
|
||||
int eth_tap_fd;
|
||||
@@ -1064,4 +1063,8 @@ TEST_CASE("esp32 l2tap - fcntl", "[ethernet][test_env=UT_T2_Ethernet]")
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_vfs_l2tap_intf_unregister(NULL));
|
||||
ethernet_deinit(ð_network_hndls);
|
||||
}
|
||||
#endif // CONFIG_ESP_NETIF_L2_TAP
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
def test_esp_netif(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('\n')
|
||||
dut.expect_exact('Enter test for running.')
|
||||
dut.write('*')
|
||||
dut.expect_unity_test_output()
|
@@ -0,0 +1,4 @@
|
||||
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
||||
|
||||
CONFIG_ESP_NETIF_L2_TAP=y
|
@@ -255,12 +255,12 @@ esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt
|
||||
// Note that Locally Administered OUI range should be used only when testing on a LAN under your control!
|
||||
uint8_t base_mac_addr[ETH_ADDR_LEN];
|
||||
ESP_GOTO_ON_ERROR(esp_efuse_mac_get_default(base_mac_addr), err, TAG, "get EFUSE MAC failed");
|
||||
u_int8_t local_mac_1[ETH_ADDR_LEN];
|
||||
uint8_t local_mac_1[ETH_ADDR_LEN];
|
||||
esp_derive_local_mac(local_mac_1, base_mac_addr);
|
||||
spi_eth_module_config[0].mac_addr = local_mac_1;
|
||||
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM > 1
|
||||
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 1);
|
||||
u_int8_t local_mac_2[ETH_ADDR_LEN];
|
||||
uint8_t local_mac_2[ETH_ADDR_LEN];
|
||||
base_mac_addr[ETH_ADDR_LEN - 1] += 1;
|
||||
esp_derive_local_mac(local_mac_2, base_mac_addr);
|
||||
spi_eth_module_config[1].mac_addr = local_mac_2;
|
||||
|
@@ -1,3 +0,0 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
TEST_COMPONENTS=esp_netif
|
||||
CONFIG_ESP_NETIF_L2_TAP=y
|
Reference in New Issue
Block a user