From d23c7690f2d31f85a1ed1679b1e6f86b6a6d10c2 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Mon, 18 Jan 2021 07:12:21 +0800 Subject: [PATCH] esp32c3: Add UTs for reset_reason --- .../{esp32 => esp_common}/test/test_attr.c | 13 +-- .../esp_system/port/arch/riscv/panic_arch.c | 6 +- .../test/test_reset_reason.c | 88 ++++++++++++++----- components/soc/esp32c3/soc_memory_layout.c | 9 +- tools/ci/config/target-test.yml | 6 +- 5 files changed, 90 insertions(+), 32 deletions(-) rename components/{esp32 => esp_common}/test/test_attr.c (92%) rename components/{esp32 => esp_system}/test/test_reset_reason.c (76%) diff --git a/components/esp32/test/test_attr.c b/components/esp_common/test/test_attr.c similarity index 92% rename from components/esp32/test/test_attr.c rename to components/esp_common/test/test_attr.c index 2c2deb85e7..45aeeabe5c 100644 --- a/components/esp32/test/test_attr.c +++ b/components/esp_common/test/test_attr.c @@ -37,14 +37,17 @@ TEST_CASE("Attributes place variables into correct sections", "[ld]") TEST_ASSERT(data_in_segment(&s_rtc_force_fast, &_rtc_force_fast_start, &_rtc_force_fast_end)); TEST_ASSERT(data_in_segment(&s_rtc_force_slow, &_rtc_force_slow_start, &_rtc_force_slow_end)); -#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM - TEST_ASSERT(data_in_segment(&s_rtc_data, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); - TEST_ASSERT(data_in_segment(&s_rtc_rodata, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); - TEST_ASSERT(data_in_segment(&s_rtc_noinit, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); -#else +#if CONFIG_ESP32_RTCDATA_IN_FAST_MEM || \ + CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM || \ + CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM || \ + CONFIG_ESP32C3_RTCDATA_IN_FAST_MEM TEST_ASSERT(data_in_segment(&s_rtc_data, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH)); TEST_ASSERT(data_in_segment(&s_rtc_rodata, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH)); TEST_ASSERT(data_in_segment(&s_rtc_noinit, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH)); +#else + TEST_ASSERT(data_in_segment(&s_rtc_data, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); + TEST_ASSERT(data_in_segment(&s_rtc_rodata, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); + TEST_ASSERT(data_in_segment(&s_rtc_noinit, (int*) SOC_RTC_DATA_LOW, (int*) SOC_RTC_DATA_HIGH)); #endif TEST_ASSERT(data_in_segment(&s_rtc_force_fast, (int*) SOC_RTC_DRAM_LOW, (int*) SOC_RTC_DRAM_HIGH)); diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index 21a283ec01..bae6dc202a 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -213,7 +213,7 @@ void panic_soc_fill_info(void *f, panic_info_t *info) const int core = esp_cache_err_get_cpuid(); info->core = core; - info->exception = PANIC_EXCEPTION_TWDT; + info->exception = PANIC_EXCEPTION_IWDT; #if SOC_CPU_NUM > 1 _Static_assert(PANIC_RSN_INTWDT_CPU0 + 1 == PANIC_RSN_INTWDT_CPU1, @@ -264,7 +264,7 @@ void panic_arch_fill_info(void *frame, panic_info_t *info) void panic_print_backtrace(const void *frame, int core) { // Basic backtrace - panic_print_str("\r\nStack memory:\n"); + panic_print_str("\r\nStack memory:\r\n"); uint32_t sp = (uint32_t)((RvExcFrame *)frame)->sp; const int per_line = 8; for (int x = 0; x < 1024; x += per_line * sizeof(uint32_t)) { @@ -274,7 +274,7 @@ void panic_print_backtrace(const void *frame, int core) for (int y = 0; y < per_line; y++) { panic_print_str("0x"); panic_print_hex(spp[y]); - panic_print_char(y == per_line - 1 ? '\n' : ' '); + panic_print_str(y == per_line - 1 ? "\r\n" : " "); } } } diff --git a/components/esp32/test/test_reset_reason.c b/components/esp_system/test/test_reset_reason.c similarity index 76% rename from components/esp32/test/test_reset_reason.c rename to components/esp_system/test/test_reset_reason.c index d07a88c21e..7819b6e6bb 100644 --- a/components/esp32/test/test_reset_reason.c +++ b/components/esp_system/test/test_reset_reason.c @@ -2,10 +2,12 @@ #include "esp_system.h" #include "esp_task_wdt.h" #include "esp_attr.h" -#include "soc/rtc_periph.h" -#include "driver/timer.h" -#include "esp32/rom/rtc.h" +#include "soc/rtc.h" +#include "hal/wdt_hal.h" #include "esp_sleep.h" +#if CONFIG_IDF_TARGET_ARCH_RISCV +#include "riscv/riscv_interrupts.h" +#endif #define RTC_BSS_ATTR __attribute__((section(".rtc.bss"))) @@ -23,6 +25,41 @@ static RTC_RODATA_ATTR uint32_t s_rtc_rodata_val = CHECK_VALUE; static RTC_FAST_ATTR uint32_t s_rtc_force_fast_val; static RTC_SLOW_ATTR uint32_t s_rtc_force_slow_val; +#if CONFIG_IDF_TARGET_ESP32 +#define DEEPSLEEP "DEEPSLEEP_RESET" +#define LOAD_STORE_ERROR "LoadStoreError" +#define RESET "SW_CPU_RESET" +#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" +#define INT_WDT "TG1WDT_SYS_RESET" +#define RTC_WDT "RTCWDT_RTC_RESET" +#ifdef CONFIG_ESP32_REV_MIN_3 +#define BROWNOUT "RTCWDT_BROWN_OUT_RESET" +#else +#define BROWNOUT "SW_CPU_RESET" +#endif // CONFIG_ESP32_REV_MIN_3 +#define STORE_ERROR "StoreProhibited" + +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#define DEEPSLEEP "DSLEEP" +#define LOAD_STORE_ERROR "LoadStoreError" +#define RESET "RTC_SW_CPU_RST" +#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" +#define INT_WDT "TG1WDT_SYS_RST" +#define RTC_WDT "RTCWDT_RTC_RST" +#define BROWNOUT "BROWN_OUT_RST" +#define STORE_ERROR "StoreProhibited" + +#elif CONFIG_IDF_TARGET_ESP32C3 +#define DEEPSLEEP "DSLEEP" +#define LOAD_STORE_ERROR "Store access fault" +#define RESET "RTC_SW_CPU_RST" +#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0" +#define INT_WDT "TG1WDT_SYS_RST" +#define RTC_WDT "RTCWDT_RTC_RST" +#define BROWNOUT "BROWNOUT_RST" +#define STORE_ERROR LOAD_STORE_ERROR + +#endif // CONFIG_IDF_TARGET_ESP32 static void setup_values(void) { @@ -44,6 +81,7 @@ TEST_CASE("reset reason ESP_RST_POWERON", "[reset][ignore]") TEST_ASSERT_EQUAL(ESP_RST_POWERON, esp_reset_reason()); } +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3) // TODO ESP32-C3 IDF-2560 static void do_deep_sleep(void) { setup_values(); @@ -63,9 +101,10 @@ static void check_reset_reason_deep_sleep(void) TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_force_slow_val); } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_DEEPSLEEP", "[reset_reason][reset=DEEPSLEEP_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_DEEPSLEEP", "[reset_reason][reset="DEEPSLEEP"]", do_deep_sleep, check_reset_reason_deep_sleep); +#endif // TODO ESP32-C3 IDF-2560 static void do_exception(void) { @@ -92,11 +131,11 @@ static void check_reset_reason_panic(void) TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val); } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after exception", "[reset_reason][reset=LoadStoreError,SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after exception", "[reset_reason][reset="LOAD_STORE_ERROR","RESET"]", do_exception, check_reset_reason_panic); -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after abort", "[reset_reason][reset=abort,SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after abort", "[reset_reason][reset=abort,"RESET"]", do_abort, check_reset_reason_panic); @@ -128,12 +167,12 @@ static void check_reset_reason_sw(void) TEST_ASSERT_EQUAL_HEX32(0, s_rtc_force_slow_val); } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart", "[reset_reason][reset=SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart", "[reset_reason][reset="RESET"]", do_restart, check_reset_reason_sw); #if portNUM_PROCESSORS > 1 -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart from APP CPU", "[reset_reason][reset=SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart from APP CPU", "[reset_reason][reset="RESET"]", do_restart_from_app_cpu, check_reset_reason_sw); #endif @@ -149,7 +188,11 @@ static void do_int_wdt(void) static void do_int_wdt_hw(void) { setup_values(); +#if CONFIG_IDF_TARGET_ARCH_RISCV + riscv_global_interrupts_disable(); +#else XTOS_SET_INTLEVEL(XCHAL_NMILEVEL); +#endif while(1); } @@ -160,12 +203,12 @@ static void check_reset_reason_int_wdt(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_INT_WDT after interrupt watchdog (panic)", - "[reset_reason][reset=Interrupt wdt timeout on CPU0,SW_CPU_RESET]", + "[reset_reason][reset="INT_WDT_PANIC","RESET"]", do_int_wdt, check_reset_reason_int_wdt); TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_INT_WDT after interrupt watchdog (hw)", - "[reset_reason][reset=TG1WDT_SYS_RESET]", + "[reset_reason][reset="INT_WDT"]", do_int_wdt_hw, check_reset_reason_int_wdt); @@ -191,18 +234,21 @@ static void check_reset_reason_task_wdt(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_TASK_WDT after task watchdog", - "[reset_reason][reset=abort,SW_CPU_RESET]", + "[reset_reason][reset=abort,"RESET"]", do_task_wdt, check_reset_reason_task_wdt); static void do_rtc_wdt(void) { setup_values(); - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM); - WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, 10000); - REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN); + // Enable RTC watchdog for 0.1 second + wdt_hal_context_t rtc_wdt_ctx; + wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); + uint32_t stage_timeout_ticks = rtc_clk_slow_freq_get_hz() / 10; + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); while(1); } @@ -213,11 +259,12 @@ static void check_reset_reason_any_wdt(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_WDT after RTC watchdog", - "[reset_reason][reset=RTCWDT_RTC_RESET]", + "[reset_reason][reset="RTC_WDT"]", do_rtc_wdt, check_reset_reason_any_wdt); +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) // TODO ESP32-C3 IDF-2397 static void do_brownout(void) { setup_values(); @@ -239,9 +286,10 @@ static void check_reset_reason_brownout(void) } TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event", - "[reset_reason][ignore][reset=SW_CPU_RESET]", + "[reset_reason][ignore][reset="BROWNOUT"]", do_brownout, check_reset_reason_brownout); +#endif // TODO ESP32-C3 IDF-2397 #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY @@ -317,11 +365,11 @@ static void test2_finish(void) printf("test - OK\n"); } -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack][reset=SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack][reset="RESET"]", init_restart_task, test1_finish); -TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a task with spiram stack", "[spiram_stack][reset=StoreProhibited,SW_CPU_RESET]", +TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a task with spiram stack", "[spiram_stack][reset="STORE_ERROR","RESET"]", init_task_do_exception, test2_finish); diff --git a/components/soc/esp32c3/soc_memory_layout.c b/components/soc/esp32c3/soc_memory_layout.c index 3078d74003..1b9ca32c31 100644 --- a/components/soc/esp32c3/soc_memory_layout.c +++ b/components/soc/esp32c3/soc_memory_layout.c @@ -72,7 +72,7 @@ const soc_memory_region_t soc_memory_regions[] = { const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t); -extern int _data_start, _heap_start, _iram_start, _iram_end; +extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_slow_end; /** * Reserved memory regions. @@ -88,4 +88,11 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d #define I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW) SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_end - I_D_OFFSET, iram_code); +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP +/* We use _rtc_force_slow_end not _rtc_noinit_end here, as rtc "fast" memory ends up in RTC SLOW + region on C3, no differentiation. And _rtc_force_slow_end is the end of all the static RTC sections. +*/ +SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); +#endif + #endif // BOOTLOADER_BUILD diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index 520d33b4a0..0e9a4919d4 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -501,7 +501,7 @@ UT_033: UT_034: extends: .unit_test_32_template - parallel: 2 + parallel: 3 tags: - ESP32_IDF - UT_T1_ESP_FLASH @@ -529,7 +529,7 @@ UT_036: UT_038: extends: .unit_test_s2_template - parallel: 2 + parallel: 3 tags: - ESP32S2_IDF - UT_T1_ESP_FLASH @@ -569,7 +569,7 @@ UT_046: UT_C3: extends: .unit_test_c3_template - parallel: 26 + parallel: 27 tags: - ESP32C3_IDF - UT_T1_1