Merge branch 'feature/case_for_ot_sleepy_ci' into 'release/v5.1'

ci(openthread): add a test case for openthread sleepy device

See merge request espressif/esp-idf!28280
This commit is contained in:
Jiang Jiang Jian
2024-02-28 10:41:10 +08:00
11 changed files with 319 additions and 36 deletions

View File

@@ -172,6 +172,20 @@
- "build:example_test" - "build:example_test"
- build:target_test - build:target_test
# For openthread sleepy
"test:example_test-otsleepy":
patterns:
- "example_test-otsleepy"
- "target_test-i154"
labels:
- target_test
- example_test
included_in:
- "build:example_test-esp32c6"
- "build:example_test-esp32h2"
- "build:example_test"
- build:target_test
"test:host_test": "test:host_test":
labels: labels:
- host_test - host_test

View File

@@ -93,6 +93,13 @@
- "examples/common_components/iperf/**/*" - "examples/common_components/iperf/**/*"
- "examples/openthread/**/*" - "examples/openthread/**/*"
.patterns-example_test-otsleepy: &patterns-example_test-otsleepy
- "components/esp_hw_support/**/*"
- "components/esp_netif/**/*"
- "components/lwip/**/*"
- "components/openthread/**/*"
- "examples/openthread/**/*"
.patterns-target_test-wifi: &patterns-target_test-wifi .patterns-target_test-wifi: &patterns-target_test-wifi
- "components/esp_netif/**/*" - "components/esp_netif/**/*"
- "components/lwip/**/*" - "components/lwip/**/*"
@@ -1121,6 +1128,8 @@
changes: *patterns-example_test-ethernet changes: *patterns-example_test-ethernet
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-i154 changes: *patterns-example_test-i154
- <<: *if-dev-push
changes: *patterns-example_test-otsleepy
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-sdio changes: *patterns-example_test-sdio
- <<: *if-dev-push - <<: *if-dev-push
@@ -1291,6 +1300,8 @@
changes: *patterns-example_test-ethernet changes: *patterns-example_test-ethernet
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-i154 changes: *patterns-example_test-i154
- <<: *if-dev-push
changes: *patterns-example_test-otsleepy
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-sdio changes: *patterns-example_test-sdio
- <<: *if-dev-push - <<: *if-dev-push
@@ -1333,6 +1344,8 @@
changes: *patterns-example_test-ethernet changes: *patterns-example_test-ethernet
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-i154 changes: *patterns-example_test-i154
- <<: *if-dev-push
changes: *patterns-example_test-otsleepy
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-sdio changes: *patterns-example_test-sdio
- <<: *if-dev-push - <<: *if-dev-push
@@ -1513,6 +1526,8 @@
changes: *patterns-example_test-ethernet changes: *patterns-example_test-ethernet
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-i154 changes: *patterns-example_test-i154
- <<: *if-dev-push
changes: *patterns-example_test-otsleepy
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-example_test-sdio changes: *patterns-example_test-sdio
- <<: *if-dev-push - <<: *if-dev-push
@@ -2634,6 +2649,20 @@
- <<: *if-dev-push - <<: *if-dev-push
changes: *patterns-target_test-i154 changes: *patterns-target_test-i154
.rules:test:example_test-otsleepy:
rules:
- <<: *if-revert-branch
when: never
- <<: *if-protected
- <<: *if-label-build-only
when: never
- <<: *if-label-example_test
- <<: *if-label-target_test
- <<: *if-dev-push
changes: *patterns-example_test-otsleepy
- <<: *if-dev-push
changes: *patterns-target_test-i154
.rules:test:host_test: .rules:test:host_test:
rules: rules:
- <<: *if-revert-branch - <<: *if-revert-branch

View File

@@ -992,6 +992,17 @@ pytest_examples_openthread_br:
- esp32c6 - esp32c6
- openthread_br - openthread_br
pytest_examples_openthread_sleep:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-otsleepy
needs:
- build_pytest_examples_esp32c6
- build_pytest_examples_esp32h2
tags:
- esp32c6
- openthread_sleep
pytest_components_esp32s3_usb_host: pytest_components_esp32s3_usb_host:
extends: extends:
- .pytest_components_dir_template - .pytest_components_dir_template

View File

@@ -172,6 +172,12 @@ menu "Hardware Settings"
For chips after esp32, the delay will be executed only in light sleep flow, the delay For chips after esp32, the delay will be executed only in light sleep flow, the delay
controlled by the EFUSE_FLASH_TPUW in ROM will be executed in deepsleep wake up flow.) controlled by the EFUSE_FLASH_TPUW in ROM will be executed in deepsleep wake up flow.)
config ESP_SLEEP_DEBUG
bool "esp sleep debug"
default n
help
Enable esp sleep debug.
config ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS config ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS
bool "Allow to enable internal pull-up/downs for the Deep-Sleep wakeup IOs" bool "Allow to enable internal pull-up/downs for the Deep-Sleep wakeup IOs"
default y default y

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,6 +13,23 @@ extern "C" {
#endif #endif
#if CONFIG_ESP_SLEEP_DEBUG
typedef struct {
uint32_t lightsleep_cnt;
uint64_t sleep_in_rtc_time_stamp;
uint64_t sleep_out_rtc_time_stamp;
uint32_t wakeup_triggers;
uint32_t sleep_flags;
esp_err_t sleep_request_result;
} esp_sleep_context_t;
/**
* @brief Set the context pointer of last sleep request
* @param sleep_ctx Structure where the context of the sleep information needs to be recorded in
*/
void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx);
#endif
/** /**
* @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode * @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -83,7 +83,6 @@
#include "esp32c2/rom/rtc.h" #include "esp32c2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C6 #elif CONFIG_IDF_TARGET_ESP32C6
#include "esp32c6/rom/rtc.h" #include "esp32c6/rom/rtc.h"
#include "hal/lp_timer_hal.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
#elif CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/rtc.h" #include "esp32h2/rom/rtc.h"
@@ -196,8 +195,10 @@ typedef struct {
uint32_t ext0_trigger_level : 1; uint32_t ext0_trigger_level : 1;
uint32_t ext0_rtc_gpio_num : 5; uint32_t ext0_rtc_gpio_num : 5;
#endif #endif
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup
uint32_t gpio_trigger_mode : 8; uint32_t gpio_trigger_mode : 8;
#endif
uint32_t sleep_time_adjustment; uint32_t sleep_time_adjustment;
uint32_t ccount_ticks_record; uint32_t ccount_ticks_record;
uint32_t sleep_time_overhead_out; uint32_t sleep_time_overhead_out;
@@ -207,6 +208,17 @@ typedef struct {
} sleep_config_t; } sleep_config_t;
#if CONFIG_ESP_SLEEP_DEBUG
static esp_sleep_context_t *s_sleep_ctx = NULL;
void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx)
{
s_sleep_ctx = sleep_ctx;
}
#endif
static uint32_t s_lightsleep_cnt = 0;
_Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size"); _Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size");
static sleep_config_t s_config = { static sleep_config_t s_config = {
@@ -715,11 +727,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
if (periph_using_8m) { if (periph_using_8m) {
sleep_flags |= RTC_SLEEP_DIG_USE_8M; sleep_flags |= RTC_SLEEP_DIG_USE_8M;
} }
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->sleep_flags = sleep_flags;
}
#endif
// Enter sleep // Enter sleep
esp_err_t result; esp_err_t result;
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED
pmu_sleep_config_t config; pmu_sleep_config_t config;
pmu_sleep_init(pmu_sleep_config_default(&config, pd_flags, s_config.sleep_time_adjustment, pmu_sleep_init(pmu_sleep_config_default(&config, sleep_flags, s_config.sleep_time_adjustment,
s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period,
deep_sleep), deep_sleep); deep_sleep), deep_sleep);
#else #else
@@ -749,6 +768,11 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
if (should_skip_sleep) { if (should_skip_sleep) {
result = ESP_ERR_SLEEP_REJECT; result = ESP_ERR_SLEEP_REJECT;
} else { } else {
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers;
}
#endif
if (deep_sleep) { if (deep_sleep) {
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
esp_sleep_isolate_digital_gpio(); esp_sleep_isolate_digital_gpio();
@@ -792,8 +816,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0);
if (pd_flags & PMU_SLEEP_PD_CPU) { if (pd_flags & PMU_SLEEP_PD_CPU) {
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
} else { } else
#endif #endif
{
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
} }
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_EXIT_SLEEP, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_EXIT_SLEEP, (void *)0);
@@ -1063,15 +1088,18 @@ esp_err_t esp_light_sleep_start(void)
*/ */
esp_clk_private_lock(); esp_clk_private_lock();
#if SOC_LP_TIMER_SUPPORTED
s_config.rtc_ticks_at_sleep_start = lp_timer_hal_get_cycle_count();
#else
s_config.rtc_ticks_at_sleep_start = rtc_time_get(); s_config.rtc_ticks_at_sleep_start = rtc_time_get();
#endif
uint32_t ccount_at_sleep_start = esp_cpu_get_cycle_count(); uint32_t ccount_at_sleep_start = esp_cpu_get_cycle_count();
esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_TIME_START, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_TIME_START, (void *)0);
uint64_t high_res_time_at_start = esp_timer_get_time(); uint64_t high_res_time_at_start = esp_timer_get_time();
uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->sleep_in_rtc_time_stamp = s_config.rtc_ticks_at_sleep_start;
}
#endif
esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_other_cpu();
// Decide which power domains can be powered down // Decide which power domains can be powered down
@@ -1164,6 +1192,13 @@ esp_err_t esp_light_sleep_start(void)
// reset light sleep wakeup flag before a new light sleep // reset light sleep wakeup flag before a new light sleep
s_light_sleep_wakeup = false; s_light_sleep_wakeup = false;
s_lightsleep_cnt++;
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->lightsleep_cnt = s_lightsleep_cnt;
}
#endif
// if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup // if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup
if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) { if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) {
err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION; err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION;
@@ -1176,13 +1211,15 @@ esp_err_t esp_light_sleep_start(void)
s_light_sleep_wakeup = (err == ESP_OK); s_light_sleep_wakeup = (err == ESP_OK);
// System timer has been stopped for the duration of the sleep, correct for that. // System timer has been stopped for the duration of the sleep, correct for that.
#if SOC_LP_TIMER_SUPPORTED
uint64_t rtc_ticks_at_end = lp_timer_hal_get_cycle_count();
#else
uint64_t rtc_ticks_at_end = rtc_time_get(); uint64_t rtc_ticks_at_end = rtc_time_get();
#endif
uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period); uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->sleep_out_rtc_time_stamp = rtc_ticks_at_end;
}
#endif
/** /**
* If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero. * If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero.
* In this case, just ignore the time compensation and keep esp_timer monotonic. * In this case, just ignore the time compensation and keep esp_timer monotonic.
@@ -1211,6 +1248,12 @@ esp_err_t esp_light_sleep_start(void)
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_EXIT_SLEEP, (void *)0); esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_EXIT_SLEEP, (void *)0);
s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
#if CONFIG_ESP_SLEEP_DEBUG
if (s_sleep_ctx != NULL) {
s_sleep_ctx->sleep_request_result = err;
}
#endif
return err; return err;
} }
@@ -1307,7 +1350,7 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
// Last timer wake-up validity check // Last timer wake-up validity check
if ((sleep_duration == 0) || \ if ((sleep_duration == 0) || \
(target_wakeup_tick < lp_timer_hal_get_cycle_count() + SLEEP_TIMER_ALARM_TO_SLEEP_TICKS)) { (target_wakeup_tick < rtc_time_get() + SLEEP_TIMER_ALARM_TO_SLEEP_TICKS)) {
// Treat too short sleep duration setting as timer reject // Treat too short sleep duration setting as timer reject
return ESP_ERR_SLEEP_REJECT; return ESP_ERR_SLEEP_REJECT;
} }
@@ -1850,7 +1893,6 @@ static uint32_t get_power_down_flags(void)
} }
#endif #endif
#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_IDF_TARGET_ESP32
s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF; s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF;
#endif #endif

View File

@@ -133,6 +133,7 @@ ENV_MARKERS = {
# multi-dut markers # multi-dut markers
'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.', 'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.',
'openthread_br': 'tests should be used for openthread border router.', 'openthread_br': 'tests should be used for openthread border router.',
'openthread_sleep': 'tests should be used for openthread sleepy device.',
'wifi_two_dut': 'tests should be run on runners which has two wifi duts connected.', 'wifi_two_dut': 'tests should be run on runners which has two wifi duts connected.',
'generic_multi_device': 'generic multiple devices whose corresponding gpio pins are connected to each other.', 'generic_multi_device': 'generic multiple devices whose corresponding gpio pins are connected to each other.',
'twai_network': 'multiple runners form a TWAI network.', 'twai_network': 'multiple runners form a TWAI network.',

View File

@@ -13,10 +13,6 @@ examples/openthread/ot_br:
examples/openthread/ot_cli: examples/openthread/ot_cli:
enable: enable:
- if: SOC_IEEE802154_SUPPORTED == 1 - if: SOC_IEEE802154_SUPPORTED == 1
disable_test:
- if: IDF_TARGET == "esp32c6"
temporary: true
reason: only test on esp32h2
examples/openthread/ot_rcp: examples/openthread/ot_rcp:
enable: enable:
@@ -37,7 +33,3 @@ examples/openthread/ot_sleepy_device/deep_sleep:
examples/openthread/ot_sleepy_device/light_sleep: examples/openthread/ot_sleepy_device/light_sleep:
enable: enable:
- if: SOC_IEEE802154_SUPPORTED == 1 - if: SOC_IEEE802154_SUPPORTED == 1
disable_test:
- if: SOC_IEEE802154_SUPPORTED == 1
temporary: true
reason: Unsupport # TO-DO: TZ-134

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0 # SPDX-License-Identifier: Unlicense OR CC0-1.0
# !/usr/bin/env python3 # !/usr/bin/env python3
# this file defines some functions for testing cli and br under pytest framework # this file defines some functions for testing cli and br under pytest framework
@@ -23,6 +23,26 @@ class thread_parameter:
self.channel = channel self.channel = channel
self.exaddr = exaddr self.exaddr = exaddr
self.bbr = bbr self.bbr = bbr
self.networkname = ''
self.panid = ''
self.extpanid = ''
self.networkkey = ''
self.pskc = ''
def setnetworkname(self, networkname:str) -> None:
self.networkname = networkname
def setpanid(self, panid:str) -> None:
self.panid = panid
def setextpanid(self, extpanid:str) -> None:
self.extpanid = extpanid
def setnetworkkey(self, networkkey:str) -> None:
self.networkkey = networkkey
def setpskc(self, pskc:str) -> None:
self.pskc = pskc
class wifi_parameter: class wifi_parameter:
@@ -34,23 +54,43 @@ class wifi_parameter:
def joinThreadNetwork(dut:IdfDut, thread:thread_parameter) -> None: def joinThreadNetwork(dut:IdfDut, thread:thread_parameter) -> None:
if thread.dataset != '': if thread.dataset:
command = 'dataset set active ' + thread.dataset command = 'dataset set active ' + thread.dataset
execute_command(dut, command) execute_command(dut, command)
dut.expect('Done', timeout=5) dut.expect('Done', timeout=5)
else: else:
execute_command(dut, 'dataset init new') execute_command(dut, 'dataset init new')
dut.expect('Done', timeout=5) dut.expect('Done', timeout=5)
execute_command(dut, 'dataset commit active') if thread.channel:
dut.expect('Done', timeout=5) command = 'dataset channel ' + thread.channel
if thread.channel != '':
command = 'channel ' + thread.channel
execute_command(dut, command) execute_command(dut, command)
dut.expect('Done', timeout=5) dut.expect('Done', timeout=5)
if thread.exaddr != '': if thread.exaddr:
command = 'extaddr ' + thread.exaddr command = 'extaddr ' + thread.exaddr
execute_command(dut, command) execute_command(dut, command)
dut.expect('Done', timeout=5) dut.expect('Done', timeout=5)
if thread.networkname:
command = 'dataset networkname ' + thread.networkname
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.panid:
command = 'dataset panid ' + thread.panid
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.extpanid:
command = 'dataset extpanid ' + thread.extpanid
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.networkkey:
command = 'dataset networkkey ' + thread.networkkey
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.pskc:
command = 'dataset pskc ' + thread.pskc
execute_command(dut, command)
dut.expect('Done', timeout=5)
execute_command(dut, 'dataset commit active')
dut.expect('Done', timeout=5)
if thread.bbr: if thread.bbr:
execute_command(dut, 'bbr enable') execute_command(dut, 'bbr enable')
dut.expect('Done', timeout=5) dut.expect('Done', timeout=5)
@@ -109,9 +149,13 @@ def getDataset(dut:IdfDut) -> str:
return str(dut_data) return str(dut_data)
def reset_thread(dut:IdfDut) -> None: def init_thread(dut:IdfDut) -> None:
dut.expect('>', timeout=10) dut.expect('>', timeout=10)
wait(dut, 3) wait(dut, 3)
reset_thread(dut)
def reset_thread(dut:IdfDut) -> None:
clean_buffer(dut) clean_buffer(dut)
execute_command(dut, 'factoryreset') execute_command(dut, 'factoryreset')
dut.expect('OpenThread attached to netif', timeout=20) dut.expect('OpenThread attached to netif', timeout=20)

View File

@@ -28,6 +28,13 @@
#include "openthread/logging.h" #include "openthread/logging.h"
#include "openthread/thread.h" #include "openthread/thread.h"
#if CONFIG_ESP_SLEEP_DEBUG
#include "esp_timer.h"
#include "esp_sleep.h"
#include "esp_private/esp_pmu.h"
#include "esp_private/esp_sleep_internal.h"
#endif
#ifdef CONFIG_PM_ENABLE #ifdef CONFIG_PM_ENABLE
#include "esp_pm.h" #include "esp_pm.h"
#endif #endif
@@ -68,6 +75,17 @@ static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t
return netif; return netif;
} }
#if CONFIG_ESP_SLEEP_DEBUG
static esp_sleep_context_t s_sleep_ctx;
static void print_sleep_flag(void *arg)
{
ESP_LOGD(TAG, "sleep_flags %lu", s_sleep_ctx.sleep_flags);
ESP_LOGD(TAG, "PMU_SLEEP_PD_TOP: %s", (s_sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP) ? "True":"False");
ESP_LOGD(TAG, "PMU_SLEEP_PD_MODEM: %s", (s_sleep_ctx.sleep_flags & PMU_SLEEP_PD_MODEM) ? "True":"False");
}
#endif
static void ot_task_worker(void *aContext) static void ot_task_worker(void *aContext)
{ {
esp_openthread_platform_config_t config = { esp_openthread_platform_config_t config = {
@@ -90,6 +108,23 @@ static void ot_task_worker(void *aContext)
create_config_network(esp_openthread_get_instance()); create_config_network(esp_openthread_get_instance());
#if CONFIG_ESP_SLEEP_DEBUG
esp_sleep_set_sleep_context(&s_sleep_ctx);
esp_log_level_set(TAG, ESP_LOG_DEBUG);
// create a timer to print the status of sleepy device
int periods = 2000;
const esp_timer_create_args_t timer_args = {
.name = "print_sleep_flag",
.arg = NULL,
.callback = &print_sleep_flag,
.skip_unhandled_events = true,
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, periods * 1000));
#endif
// Run the main loop // Run the main loop
esp_openthread_launch_mainloop(); esp_openthread_launch_mainloop();

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0 # SPDX-License-Identifier: Unlicense OR CC0-1.0
# !/usr/bin/env python3 # !/usr/bin/env python3
@@ -91,9 +91,9 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
cli_list = [cli_h2] cli_list = [cli_h2]
router_extaddr_list = ['7766554433221101'] router_extaddr_list = ['7766554433221101']
ocf.reset_thread(br) ocf.init_thread(br)
for cli in cli_list: for cli in cli_list:
ocf.reset_thread(cli) ocf.init_thread(cli)
br_ot_para = default_br_ot_para br_ot_para = default_br_ot_para
ocf.joinThreadNetwork(br, br_ot_para) ocf.joinThreadNetwork(br, br_ot_para)
cli_ot_para = default_cli_ot_para cli_ot_para = default_cli_ot_para
@@ -125,8 +125,8 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
# / \ # / \
# Wi-FI_Host Thread_End_Device # Wi-FI_Host Thread_End_Device
def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None: def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None:
ocf.reset_thread(br) ocf.init_thread(br)
ocf.reset_thread(cli) ocf.init_thread(cli)
ocf.joinWiFiNetwork(br, default_br_wifi_para) ocf.joinWiFiNetwork(br, default_br_wifi_para)
ocf.joinThreadNetwork(br, default_br_ot_para) ocf.joinThreadNetwork(br, default_br_ot_para)
ot_para = default_cli_ot_para ot_para = default_cli_ot_para
@@ -540,3 +540,95 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N
ocf.execute_command(cli, 'factoryreset') ocf.execute_command(cli, 'factoryreset')
time.sleep(3) time.sleep(3)
assert b'hello' in mytcp.tcp_bytes assert b'hello' in mytcp.tcp_bytes
# Case 10: Sleepy device test
@pytest.mark.esp32h2
@pytest.mark.esp32c6
@pytest.mark.openthread_sleep
@pytest.mark.parametrize(
'config, count, app_path, target', [
('cli_h2|sleepy_c6', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_cli")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device/light_sleep")}',
'esp32h2|esp32c6'),
('cli_c6|sleepy_h2', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_cli")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device/light_sleep")}',
'esp32c6|esp32h2'),
],
indirect=True,
)
def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None:
leader = dut[0]
sleepy_device = dut[1]
fail_info = re.compile(r'Core\W*?\d\W*?register dump')
try:
ocf.init_thread(leader)
time.sleep(3)
leader_para = ocf.thread_parameter('leader', '', '12', '7766554433221100', False)
leader_para.setnetworkname('OpenThread-ESP')
leader_para.setpanid('0x1234')
leader_para.setextpanid('dead00beef00cafe')
leader_para.setnetworkkey('aabbccddeeff00112233445566778899')
leader_para.setpskc('104810e2315100afd6bc9215a6bfac53')
ocf.joinThreadNetwork(leader, leader_para)
ocf.wait(leader, 5)
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=5)
assert not bool(fail_info.search(str(output)))
ocf.clean_buffer(sleepy_device)
sleepy_device.serial.hard_reset()
info = sleepy_device.expect(r'(.+)detached -> child', timeout=20)[1].decode(errors='replace')
assert not bool(fail_info.search(str(info)))
info = sleepy_device.expect(r'(.+)PMU_SLEEP_PD_TOP: True', timeout=10)[1].decode(errors='replace')
assert not bool(fail_info.search(str(info)))
info = sleepy_device.expect(r'(.+)PMU_SLEEP_PD_MODEM: True', timeout=20)[1].decode(errors='replace')
assert not bool(fail_info.search(str(info)))
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=20)
assert not bool(fail_info.search(str(output)))
ocf.clean_buffer(sleepy_device)
ocf.execute_command(leader, 'factoryreset')
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=5)
assert not bool(fail_info.search(str(output)))
finally:
ocf.execute_command(leader, 'factoryreset')
time.sleep(3)
# Case 11: Basic startup Test of BR
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.esp32c6
@pytest.mark.openthread_br
@pytest.mark.flaky(reruns=1, reruns_delay=1)
@pytest.mark.parametrize(
'config, count, app_path, target', [
('rcp|br', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_br")}',
'esp32c6|esp32s3'),
],
indirect=True,
)
def test_basic_startup(dut: Tuple[IdfDut, IdfDut]) -> None:
br = dut[1]
dut[0].serial.stop_redirect_thread()
try:
ocf.init_thread(br)
time.sleep(3)
ocf.clean_buffer(br)
ocf.execute_command(br, 'ifconfig up')
br.expect('Done', timeout=5)
ocf.execute_command(br, 'thread start')
br.expect('Done', timeout=5)
assert ocf.wait_for_join(br, 'leader')
ocf.reset_thread(br)
ocf.joinWiFiNetwork(br, default_br_wifi_para)
ocf.execute_command(br, 'ifconfig up')
br.expect('Done', timeout=5)
ocf.execute_command(br, 'thread start')
br.expect('Done', timeout=5)
assert ocf.wait_for_join(br, 'leader')
finally:
ocf.execute_command(br, 'factoryreset')
time.sleep(3)