| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*
- * Note: Currently, the backtraces must still be checked manually. Therefore,
- * these test cases should always pass.
- * Todo: Automate the checking of backtrace addresses.
- */
- #include <stdlib.h>
- #include "unity.h"
- #if __XTENSA__
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/xtensa_api.h"
- #include "esp_intr_alloc.h"
- #include "esp_rom_sys.h"
- #include "esp_rom_uart.h"
- #define SW_ISR_LEVEL_1 7
- #define SW_ISR_LEVEL_3 29
- #define RECUR_DEPTH 3
- #define ACTION_ABORT -1
- #define ACTION_INT_WDT -2
- // Set to (-1) for abort(), (-2) for interrupt watchdog
- static int backtrace_trigger_source;
- /*
- * Recursive functions to generate a longer call stack. When the max specified
- * recursion depth is reached, the following actions can be taken.
- */
- static void __attribute__((__noinline__)) recursive_func(int recur_depth, int action)
- {
- if (recur_depth > 1) {
- recursive_func(recur_depth - 1, action);
- } else if (action >= 0) {
- xt_set_intset(1 << action);
- } else if (action == ACTION_ABORT) {
- abort();
- // Todo: abort() causes problems in GDB Stub backtrace due to being 'non returning'.
- } else if (action == ACTION_INT_WDT) {
- portDISABLE_INTERRUPTS();
- while (1) {
- ;
- }
- }
- }
- static void level_three_isr (void *arg)
- {
- xt_set_intclear(1 << SW_ISR_LEVEL_3); //Clear interrupt
- recursive_func(RECUR_DEPTH, backtrace_trigger_source); //Abort at the max recursive depth
- }
- static void level_one_isr(void *arg)
- {
- xt_set_intclear(1 << SW_ISR_LEVEL_1); //Clear interrupt
- recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_3); //Trigger nested interrupt max recursive depth
- }
- TEST_CASE("Test backtrace from abort", "[reset_reason][reset=abort,SW_CPU_RESET]")
- {
- //Allocate level one and three SW interrupts
- esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, 0, level_one_isr, NULL, NULL); //Level 1 SW intr
- esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, 0, level_three_isr, NULL, NULL); //Level 3 SW intr
- backtrace_trigger_source = ACTION_ABORT;
- recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_1); //Trigger lvl 1 SW interrupt at max recursive depth
- }
- TEST_CASE("Test backtrace from interrupt watchdog timeout", "[reset_reason][reset=Interrupt wdt timeout on CPU0,SW_CPU_RESET]")
- {
- //Allocate level one and three SW interrupts
- esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, 0, level_one_isr, NULL, NULL); //Level 1 SW intr
- esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, 0, level_three_isr, NULL, NULL); //Level 3 SW intr
- backtrace_trigger_source = ACTION_INT_WDT;
- recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_1); //Trigger lvl 1 SW interrupt at max recursive depth
- }
- static void write_char_crash(char c)
- {
- esp_rom_uart_putc(c);
- *(char*) 0x00000001 = 0;
- }
- TEST_CASE("Test backtrace with a ROM function", "[reset_reason][reset=StoreProhibited,SW_CPU_RESET]")
- {
- ets_install_putc1(&write_char_crash);
- esp_rom_printf("foo");
- }
- #endif
|