ci(esp_eth): added ESP32P4 to iperf CI test

Updated (increased) ETH_THROUGHPUT_SPI_ETH limits.
Improved iperf optimization description
This commit is contained in:
Ondrej Kosta 2024-12-10 11:39:28 +01:00
parent 2ebbfef5f4
commit a2eba1e25a
14 changed files with 164 additions and 57 deletions

View File

@ -69,16 +69,16 @@
#endif
#ifndef IDF_PERFORMANCE_MIN_TCP_RX_ETH_THROUGHPUT_SPI_ETH
#define IDF_PERFORMANCE_MIN_TCP_RX_ETH_THROUGHPUT_SPI_ETH 2
#define IDF_PERFORMANCE_MIN_TCP_RX_ETH_THROUGHPUT_SPI_ETH 6
#endif
#ifndef IDF_PERFORMANCE_MIN_TCP_TX_ETH_THROUGHPUT_SPI_ETH
#define IDF_PERFORMANCE_MIN_TCP_TX_ETH_THROUGHPUT_SPI_ETH 3
#define IDF_PERFORMANCE_MIN_TCP_TX_ETH_THROUGHPUT_SPI_ETH 8
#endif
#ifndef IDF_PERFORMANCE_MIN_UDP_RX_ETH_THROUGHPUT_SPI_ETH
#define IDF_PERFORMANCE_MIN_UDP_RX_ETH_THROUGHPUT_SPI_ETH 5
#define IDF_PERFORMANCE_MIN_UDP_RX_ETH_THROUGHPUT_SPI_ETH 8
#endif
#ifndef IDF_PERFORMANCE_MIN_UDP_TX_ETH_THROUGHPUT_SPI_ETH
#define IDF_PERFORMANCE_MIN_UDP_TX_ETH_THROUGHPUT_SPI_ETH 7
#define IDF_PERFORMANCE_MIN_UDP_TX_ETH_THROUGHPUT_SPI_ETH 10
#endif

View File

@ -17,7 +17,7 @@ examples/ethernet/basic:
examples/ethernet/iperf:
disable_test:
- if: IDF_TARGET not in ["esp32"]
- if: IDF_TARGET not in ["esp32", "esp32p4"]
temporary: true
reason: lack of runners
depends_components:

View File

@ -53,6 +53,8 @@ def test_esp_eth_iperf(
dut: Dut,
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
udp_tx_bw_lim: Optional[int] = NO_BANDWIDTH_LIMIT,
udp_rx_bw_lim: Optional[int] = NO_BANDWIDTH_LIMIT,
spi_eth: Optional[bool] = False
) -> None:
"""
@ -79,12 +81,8 @@ def test_esp_eth_iperf(
# 3. run test for TCP Tx, Rx and UDP Tx, Rx
test_utility.run_test('tcp', 'tx', 0, NO_BANDWIDTH_LIMIT)
test_utility.run_test('tcp', 'rx', 0, NO_BANDWIDTH_LIMIT)
test_utility.run_test('udp', 'tx', 0, 80)
# Limit speed to 10Mbps for SPI Ethernet PHYs
if spi_eth:
test_utility.run_test('udp', 'rx', 0, 10)
else:
test_utility.run_test('udp', 'rx', 0, NO_BANDWIDTH_LIMIT)
test_utility.run_test('udp', 'tx', 0, udp_tx_bw_lim)
test_utility.run_test('udp', 'rx', 0, udp_rx_bw_lim)
# 4. log performance and compare with pass standard
for throughput_type in test_result:
@ -113,7 +111,20 @@ def test_esp_eth_iperf_ip101(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance)
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90)
@pytest.mark.esp32p4
@pytest.mark.eth_ip101
@pytest.mark.parametrize('config', [
'default_ip101_esp32p4',
], indirect=True)
def test_esp_eth_iperf_ip101_esp32p4(
dut: Dut,
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=96)
@pytest.mark.esp32
@ -126,7 +137,7 @@ def test_esp_eth_iperf_lan8720(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance)
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90)
@pytest.mark.esp32
@ -139,7 +150,7 @@ def test_esp_eth_iperf_rtl8201(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance)
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90)
@pytest.mark.esp32
@ -152,7 +163,7 @@ def test_esp_eth_iperf_dp83848(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance)
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90)
@pytest.mark.esp32
@ -165,7 +176,7 @@ def test_esp_eth_iperf_ksz8041(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance)
test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90)
@pytest.mark.esp32
@ -178,7 +189,7 @@ def test_esp_eth_iperf_dm9051(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True)
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True, udp_rx_bw_lim=10)
@pytest.mark.esp32
@ -191,7 +202,7 @@ def test_esp_eth_iperf_w5500(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True)
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True, udp_rx_bw_lim=10)
@pytest.mark.esp32
@ -204,4 +215,4 @@ def test_esp_eth_iperf_ksz8851snl(
log_performance: Callable[[str, object], None],
check_performance: Callable[[str, float, str], None],
) -> None:
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True)
test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True, udp_rx_bw_lim=10)

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -0,0 +1,49 @@
CONFIG_IDF_TARGET="esp32p4"
# Increase main task stack size
CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168
# Enable filesystem for console commands history storage
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
# Enable FreeRTOS stats formatting functions, needed for 'tasks' command
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y
# Disable watch dog
CONFIG_ESP_INT_WDT=n
CONFIG_ESP_TASK_WDT_EN=n
# Enable lwIP IRAM optimization
CONFIG_LWIP_IRAM_OPTIMIZATION=y
# Enable Ethernet IRAM optimization
CONFIG_ETH_IRAM_OPTIMIZATION=y
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=31
CONFIG_EXAMPLE_ETH_MDIO_GPIO=52
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=51
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_ETH_ENABLED=y
CONFIG_ETH_USE_ESP32_EMAC=y
CONFIG_ETH_PHY_INTERFACE_RMII=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -14,9 +14,13 @@ CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
# --------------------------------
# Performance optimization options
# --------------------------------
# `lwIP` and `iperf` tasks have serial dependency to each other (i.e. `iperf` must wait for `lwIP`
# to process the packets). Therefore, you don't gain much performance improvement when running
# multi core mode. On the other hand, IRAM optimizations have greater effect for single core mode.
# The lwIP and iperf tasks have a serial dependency (i.e., iperf must wait for lwIP to process packets),
# meaning that running in multi-core mode does not significantly improve performance. Additionally,
# IRAM optimizations have a more noticeable effect in single-core mode.
# However, while a single-core configuration can enhance iperf performance in controlled or isolated
# testing scenarios, it may not be optimal for real-world applications where the system also needs to
# handle additional, non-network-related tasks. In such cases, multi-core configurations might be better
# suited for balancing workloads and ensuring overall system responsiveness.
# Run FreeRTOS only on the first core
CONFIG_FREERTOS_UNICORE=y

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
@ -355,14 +355,14 @@ class IperfTestUtility(object):
else:
process.terminate()
else:
self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME))
# wait until DUT TCP server created
try:
self.dut.expect('Socket bound', timeout=5)
except pexpect.TIMEOUT:
# compatible with old iperf example binary
logging.info('create iperf udp server fail')
if bw_limit > 0:
self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME))
# wait until DUT TCP server created
try:
self.dut.expect('Socket bound', timeout=5)
except pexpect.TIMEOUT:
# compatible with old iperf example binary
logging.info('create iperf udp server fail')
process = subprocess.Popen(['iperf', '-c', dut_ip, '-u', '-b', str(bw_limit) + 'm',
'-t', str(TEST_TIME), '-f', 'm'], stdout=f, stderr=f)
for _ in range(TEST_TIMEOUT):
@ -372,9 +372,20 @@ class IperfTestUtility(object):
else:
process.terminate()
else:
for bandwidth in range(50, 101, 5):
start_bw = 50
stop_bw = 100
n = 10
step = int((stop_bw - start_bw) / n)
self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME + 4 * (n + 1))) # 4 sec for each bw step instance start/stop
# wait until DUT TCP server created
try:
self.dut.expect('Socket bound', timeout=5)
except pexpect.TIMEOUT:
# compatible with old iperf example binary
logging.info('create iperf udp server fail')
for bandwidth in range(start_bw, stop_bw, step):
process = subprocess.Popen(['iperf', '-c', dut_ip, '-u', '-b', str(bandwidth) + 'm',
'-t', str(TEST_TIME / 11), '-f', 'm'], stdout=f, stderr=f)
'-t', str(TEST_TIME / (n + 1)), '-f', 'm'], stdout=f, stderr=f)
for _ in range(TEST_TIMEOUT):
if process.poll() is not None:
break
@ -382,7 +393,7 @@ class IperfTestUtility(object):
else:
process.terminate()
server_raw_data = self.dut.expect(pexpect.TIMEOUT, timeout=0).decode('utf-8')
server_raw_data = self.dut.expect(pexpect.TIMEOUT, timeout=5).decode('utf-8')
with open(PC_IPERF_TEMP_LOG_FILE, 'r') as f:
pc_raw_data = f.read()