mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/panic_handler_not_in_iram' into 'master'
panic: handlers can now be placed in flash Closes IDF-2851 See merge request espressif/esp-idf!12874
This commit is contained in:
commit
e6fd582fdf
@ -394,10 +394,10 @@ menu "ESP System Settings"
|
||||
automatically re-enable flash cache before running GDB Stub or Core Dump. This adds some minor
|
||||
risk, if the flash cache status is also corrupted during the crash.
|
||||
|
||||
If this option is enabled, the panic handler code is placed in IRAM. This allows the panic
|
||||
handler to run without needing to re-enable cache first. This may be necessary to debug some
|
||||
complex issues with crashes while flash cache is disabled (for example, when writing to
|
||||
SPI flash.)
|
||||
If this option is enabled, the panic handler code (including required UART functions) is placed
|
||||
in IRAM. This may be necessary to debug some complex issues with crashes while flash cache is
|
||||
disabled (for example, when writing to SPI flash) or when flash cache is corrupted when an exception
|
||||
is triggered.
|
||||
|
||||
config ESP_DEBUG_STUBS_ENABLE
|
||||
bool
|
||||
|
@ -1,10 +1,11 @@
|
||||
[mapping:esp_system]
|
||||
archive: libesp_system.a
|
||||
entries:
|
||||
panic (noflash)
|
||||
panic_handler (noflash)
|
||||
panic_arch (noflash)
|
||||
reset_reason (noflash)
|
||||
if ESP_PANIC_HANDLER_IRAM = y:
|
||||
panic (noflash)
|
||||
panic_handler (noflash)
|
||||
panic_arch (noflash)
|
||||
|
||||
esp_err (noflash)
|
||||
esp_system:esp_system_abort (noflash)
|
||||
|
||||
|
@ -162,14 +162,6 @@ static void panic_handler(void *frame, bool pseudo_excause)
|
||||
esp_dport_access_int_abort();
|
||||
#endif
|
||||
|
||||
#if !CONFIG_ESP_PANIC_HANDLER_IRAM
|
||||
// Re-enable CPU cache for current CPU if it was disabled
|
||||
if (!spi_flash_cache_enabled()) {
|
||||
spi_flash_enable_cache(core_id);
|
||||
panic_print_str("Re-enable cpu cache.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
#if __XTENSA__
|
||||
if (!(esp_ptr_executable(cpu_ll_pc_to_ptr(panic_get_address(frame))) && (panic_get_address(frame) & 0xC0000000U))) {
|
||||
@ -198,8 +190,25 @@ static void panic_handler(void *frame, bool pseudo_excause)
|
||||
esp_panic_handler(&info);
|
||||
}
|
||||
|
||||
void panicHandler(void *frame)
|
||||
/**
|
||||
* This function must always be in IRAM as it is required to
|
||||
* re-enable the flash cache.
|
||||
*/
|
||||
static void IRAM_ATTR panic_enable_cache(void) {
|
||||
int core_id = cpu_hal_get_core_id();
|
||||
|
||||
if (!spi_flash_cache_enabled()) {
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
esp_dport_access_int_abort();
|
||||
#endif
|
||||
spi_flash_enable_cache(core_id);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR panicHandler(void *frame)
|
||||
{
|
||||
|
||||
panic_enable_cache();
|
||||
// This panic handler gets called for when the double exception vector,
|
||||
// kernel exception vector gets used; as well as handling interrupt-based
|
||||
// faults cache error, wdt expiry. EXCAUSE register gets written with
|
||||
@ -207,8 +216,9 @@ void panicHandler(void *frame)
|
||||
panic_handler(frame, true);
|
||||
}
|
||||
|
||||
void xt_unhandled_exception(void *frame)
|
||||
void IRAM_ATTR xt_unhandled_exception(void *frame)
|
||||
{
|
||||
panic_enable_cache();
|
||||
panic_handler(frame, false);
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ esp_reset_reason_t IRAM_ATTR esp_reset_reason_get_hint(void)
|
||||
}
|
||||
return (esp_reset_reason_t) low;
|
||||
}
|
||||
static void esp_reset_reason_clear_hint(void)
|
||||
static inline void esp_reset_reason_clear_hint(void)
|
||||
{
|
||||
REG_WRITE(RTC_RESET_CAUSE_REG, 0);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ archive: libhal.a
|
||||
entries:
|
||||
spi_hal_iram (noflash)
|
||||
spi_slave_hal_iram (noflash)
|
||||
if UART_ISR_IN_IRAM = y:
|
||||
if UART_ISR_IN_IRAM = y || ESP_PANIC_HANDLER_IRAM = y:
|
||||
uart_hal_iram (noflash)
|
||||
else:
|
||||
uart_hal_iram (default)
|
||||
|
@ -67,7 +67,7 @@ Behavior of panic handler is affected by two other configuration options.
|
||||
|
||||
- If :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM` is disabled (disabled by default), the panic handler code is placed in flash memory not IRAM. This means that if ESP-IDF crashes while flash cache is disabled, the panic handler will automatically re-enable flash cache before running GDB Stub or Core Dump. This adds some minor risk, if the flash cache status is also corrupted during the crash.
|
||||
|
||||
If this option is enabled, the panic handler code is placed in IRAM. This allows the panic handler to run without needing to re-enable cache first. This may be necessary to debug some complex issues with crashes while flash cache is disabled (for example, when writing to SPI flash).
|
||||
If this option is enabled, the panic handler code (including required UART functions) is placed in IRAM. This may be necessary to debug some complex issues with crashes while flash cache is disabled (for example, when writing to SPI flash) or when flash cache is corrupted when an exception is triggered.
|
||||
|
||||
The following diagram illustrates panic handler behavior:
|
||||
|
||||
|
@ -73,7 +73,6 @@ def int_wdt_inner(env, test_name):
|
||||
|
||||
def int_wdt_cache_disabled_inner(env, test_name):
|
||||
with get_dut(env, test_name, 'test_int_wdt_cache_disabled', qemu_wdt_enable=True) as dut:
|
||||
dut.expect('Re-enable cpu cache.')
|
||||
dut.expect_gme('Interrupt wdt timeout on CPU0')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect('Backtrace:')
|
||||
@ -87,7 +86,6 @@ def int_wdt_cache_disabled_inner(env, test_name):
|
||||
|
||||
def cache_error_inner(env, test_name):
|
||||
with get_dut(env, test_name, 'test_cache_error') as dut:
|
||||
dut.expect('Re-enable cpu cache.')
|
||||
dut.expect_gme('Cache disabled but cached memory region accessed')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
|
Loading…
Reference in New Issue
Block a user