From c2dac74cc5e95bb21548bdce6f6039b144531560 Mon Sep 17 00:00:00 2001 From: maojianxin Date: Thu, 19 Mar 2020 22:50:59 +0800 Subject: [PATCH] Fix psram task coredump block Fix coredump erase flash delay --- components/esp32/include/esp_panic.h | 11 +++++++++-- components/esp32/panic.c | 14 +++++++++----- components/spi_flash/cache_utils.c | 14 ++++++++++---- components/spi_flash/flash_ops.c | 28 +++++++++++++++++----------- 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h index 2d250203e4..93ed13b2ea 100644 --- a/components/esp32/include/esp_panic.h +++ b/components/esp32/include/esp_panic.h @@ -23,7 +23,7 @@ extern "C" #include "soc/soc.h" /** - * @brief If an OCD is connected over JTAG. set breakpoint 0 to the given function + * @brief If an OCD is connected over JTAG. set breakpoint 0 to the given function * address. Do nothing otherwise. * @param data Pointer to the target breakpoint position */ @@ -45,7 +45,7 @@ void esp_set_breakpoint_if_jtag(void *fn); * * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise * - * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively + * @warning The ESP32 watchpoint hardware watches a region of bytes by effectively * masking away the lower n bits for a region with size 2^n. If adr does * not have zero for these lower n bits, you may not be watching the * region you intended. @@ -61,6 +61,13 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags); */ void esp_clear_watchpoint(int no); +/** + * @brief check in panic status + * + * return ture is in panic status + */ +bool esp_check_in_panic_status(void); + /** * @brief Checks stack pointer */ diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 070c8f4c82..ca89b5858a 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -47,6 +47,8 @@ #include "SEGGER_RTT.h" #endif +static bool g_panic_interrupt_state = false; + #if CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO == -1 #define APPTRACE_ONPANIC_HOST_FLUSH_TMO ESP_APPTRACE_TMO_INFINITE #else @@ -433,6 +435,7 @@ static inline void disableAllWdts() TIMERG0.wdt_config0.en = 0; TIMERG0.wdt_wprotect = 0; TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; + TIMERG1.int_clr_timers.wdt = 1; TIMERG1.wdt_config0.en = 0; TIMERG1.wdt_wprotect = 0; } @@ -621,11 +624,8 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) disableAllWdts(); s_dumping_core = true; #if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH - if (xPortGetCoreID() == APP_CPU_NUM) { - panicPutStr("Current task in APP CPU, skip...\n"); - } else { - esp_core_dump_to_flash(frame); - } + g_panic_interrupt_state = true; + esp_core_dump_to_flash(frame); #endif #if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP32_PANIC_SILENT_REBOOT esp_core_dump_to_uart(frame); @@ -659,6 +659,10 @@ void esp_set_breakpoint_if_jtag(void *fn) } } +bool esp_check_in_panic_status(void) +{ + return g_panic_interrupt_state; +} esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) { diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index a6b585478f..57955e1327 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -62,7 +62,7 @@ void spi_flash_op_unlock() } /* If you're going to modify this, keep in mind that while the flash caches of the pro and app - cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine + cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine with its cache enabled but the other CPUs cache is not enabled yet, you will have problems when accessing psram from the former CPU. */ @@ -133,7 +133,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() } // Kill interrupts that aren't located in IRAM esp_intr_noniram_disable(); - // This CPU executes this routine, with non-IRAM interrupts and the scheduler + // This CPU executes this routine, with non-IRAM interrupts and the scheduler // disabled. The other CPU is spinning in the spi_flash_op_block_func task, also // with non-iram interrupts and the scheduler disabled. None of these CPUs will // touch external RAM or flash this way, so we can safely disable caches. @@ -183,10 +183,10 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os() const uint32_t cpuid = xPortGetCoreID(); const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; - // do not care about other CPU, it was halted upon entering panic handler - spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); // Kill interrupts that aren't located in IRAM esp_intr_noniram_disable(); + // do not care about other CPU, it was halted upon entering panic handler + spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); // Disable cache on this CPU as well spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); } @@ -194,9 +194,11 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu_no_os() void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os() { const uint32_t cpuid = xPortGetCoreID(); + const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; // Re-enable cache on this CPU spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); + spi_flash_restore_cache(other_cpuid, s_flash_op_cache_state[other_cpuid]); // Re-enable non-iram interrupts esp_intr_noniram_enable(); } @@ -220,6 +222,10 @@ void spi_flash_op_unlock() void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() { + if (esp_ptr_external_ram(get_sp())) { + ets_printf(DRAM_STR("Cache disabled but cache memory accesed!\n")); + __asm__ __volatile__ ("ill.n\nill.n\n"); + } spi_flash_op_lock(); esp_intr_noniram_disable(); spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index b535e80085..11b5ef5dce 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -35,6 +35,7 @@ #include "esp_ota_ops.h" #include "cache_utils.h" #include "esp_timer.h" +#include "esp_panic.h" /* bytes erased by SPIEraseBlock() ROM function */ #define BLOCK_ERASE_SIZE 65536 @@ -217,6 +218,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) if (size + start_addr > spi_flash_get_chip_size()) { return ESP_ERR_INVALID_SIZE; } + int64_t start_time_us = 0; size_t start = start_addr / SPI_FLASH_SEC_SIZE; size_t end = start + size / SPI_FLASH_SEC_SIZE; const size_t sectors_per_block = BLOCK_ERASE_SIZE / SPI_FLASH_SEC_SIZE; @@ -225,9 +227,11 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) rc = spi_flash_unlock(); if (rc == ESP_ROM_SPIFLASH_RESULT_OK) { for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) { + if (!esp_check_in_panic_status()) { #ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE - int64_t start_time_us = esp_timer_get_time(); + start_time_us = esp_timer_get_time(); #endif + } spi_flash_guard_start(); if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) { rc = esp_rom_spiflash_erase_block(sector / sectors_per_block); @@ -239,17 +243,19 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE); } spi_flash_guard_end(); -#ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE - int dt_ms = (esp_timer_get_time() - start_time_us) / 1000; - if (dt_ms >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS || - dt_ms * 2 >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS) { - /* For example when dt_ms = 15 and CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS = 20. - * In this case we need to call vTaskDelay because - * the duration of this command + the next command probably will exceed more than 20. - */ - vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS); + if (!esp_check_in_panic_status()) { + #ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE + int dt_ms = (esp_timer_get_time() - start_time_us) / 1000; + if (dt_ms >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS || + dt_ms * 2 >= CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS) { + /* For example when dt_ms = 15 and CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS = 20. + * In this case we need to call vTaskDelay because + * the duration of this command + the next command probably will exceed more than 20. + */ + vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS); + } + #endif } -#endif } } COUNTER_STOP(erase);