diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 4ac1685d0..8e02e184c 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -31,7 +31,7 @@ config SPIRAM_SUPPORT bool "Support for external, SPI-connected RAM" default "n" help - This enables support for an external SPI RAM chip, connected in parallel with the + This enables support for an external SPI RAM chip, connected in parallel with the main SPI flash chip. menu "SPI RAM config" @@ -122,7 +122,7 @@ config SPIRAM_CACHE_WORKAROUND Revision 1 of the ESP32 has a bug that can cause a write to PSRAM not to take place in some situations when the cache line needs to be fetched from external RAM and an interrupt occurs. This enables a fix in the compiler that makes sure the specific code that is vulnerable to this will not be emitted. - + This will also not use any bits of newlib that are located in ROM, opting for a version that is compiled with the workaround and located in flash instead. @@ -137,7 +137,7 @@ config SPIRAM_MALLOC_ALWAYSINTERNAL than this size in internal memory, while allocations larger than this will be done from external RAM. If allocation from the preferred region fails, an attempt is made to allocate from the non-preferred region instead, so malloc() will not suddenly fail when either internal or external memory is full. - + config WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST bool "Try to allocate memories of WiFi and LWIP in SPIRAM firstly. If failed, allocate internal memory" depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC @@ -153,12 +153,12 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL help Because the external/internal RAM allocation strategy is not always perfect, it sometimes may happen that the internal memory is entirely filled up. This causes allocations that are specifically done in - internal memory, for example the stack for new tasks or memory to service DMA or have memory that's - also available when SPI cache is down, to fail. This option reserves a pool specifically for requests + internal memory, for example the stack for new tasks or memory to service DMA or have memory that's + also available when SPI cache is down, to fail. This option reserves a pool specifically for requests like that; the memory in this pool is not given out when a normal malloc() is called. - + Set this to 0 to disable this feature. - + Note that because FreeRTOS stacks are forced to internal memory, they will also use this memory pool; be sure to keep this in mind when adjusting this value. @@ -218,8 +218,8 @@ choice ESP32_COREDUMP_TO_FLASH_OR_UART help Select place to store core dump: flash, uart or none (to disable core dumps generation). - If core dump is configured to be stored in flash and custom partition table is used add - corresponding entry to your CSV. For examples, please see predefined partition table CSV descriptions + If core dump is configured to be stored in flash and custom partition table is used add + corresponding entry to your CSV. For examples, please see predefined partition table CSV descriptions in the components/partition_table directory. config ESP32_ENABLE_COREDUMP_TO_FLASH @@ -258,18 +258,18 @@ choice NUMBER_OF_UNIVERSAL_MAC_ADDRESS default FOUR_UNIVERSAL_MAC_ADDRESS help Configure the number of universally administered (by IEEE) MAC addresses. - During initialisation, MAC addresses for each network interface are generated or derived from a + During initialisation, MAC addresses for each network interface are generated or derived from a single base MAC address. - If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap, - Bluetooth and Ethernet) receive a universally administered MAC address. These are generated + If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap, + Bluetooth and Ethernet) receive a universally administered MAC address. These are generated sequentially by adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address. - If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth) - receive a universally administered MAC address. These are generated sequentially by adding 0 - and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet) - receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC + If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth) + receive a universally administered MAC address. These are generated sequentially by adding 0 + and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet) + receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC addresses, respectively. - When using the default (Espressif-assigned) base MAC address, either setting can be used. When using - a custom universal MAC address range, the correct setting will depend on the allocation of MAC + When using the default (Espressif-assigned) base MAC address, either setting can be used. When using + a custom universal MAC address range, the correct setting will depend on the allocation of MAC addresses in this range (either 2 or 4 per device.) config TWO_UNIVERSAL_MAC_ADDRESS @@ -279,7 +279,7 @@ config FOUR_UNIVERSAL_MAC_ADDRESS endchoice config NUMBER_OF_UNIVERSAL_MAC_ADDRESS - int + int default 2 if TWO_UNIVERSAL_MAC_ADDRESS default 4 if FOUR_UNIVERSAL_MAC_ADDRESS @@ -327,10 +327,10 @@ config TIMER_TASK_STACK_SIZE to dispatch callbacks of timers created using ets_timer and esp_timer APIs. If you are seing stack overflow errors in timer task, increase this value. - + Note that this is not the same as FreeRTOS timer task. To configure FreeRTOS timer task size, see "FreeRTOS timer task stack size" option - in "FreeRTOS" menu. + in "FreeRTOS" menu. choice NEWLIB_STDOUT_LINE_ENDING prompt "Line ending for UART output" @@ -339,15 +339,15 @@ choice NEWLIB_STDOUT_LINE_ENDING This option allows configuring the desired line endings sent to UART when a newline ('\n', LF) appears on stdout. Three options are possible: - + CRLF: whenever LF is encountered, prepend it with CR - + LF: no modification is applied, stdout is sent as is - + CR: each occurence of LF is replaced with CR - + This option doesn't affect behavior of the UART driver (drivers/uart.h). - + config NEWLIB_STDOUT_LINE_ENDING_CRLF bool "CRLF" config NEWLIB_STDOUT_LINE_ENDING_LF @@ -363,15 +363,15 @@ choice NEWLIB_STDIN_LINE_ENDING This option allows configuring which input sequence on UART produces a newline ('\n', LF) on stdin. Three options are possible: - + CRLF: CRLF is converted to LF - + LF: no modification is applied, input is sent to stdin as is - + CR: each occurence of CR is replaced with LF - + This option doesn't affect behavior of the UART driver (drivers/uart.h). - + config NEWLIB_STDIN_LINE_ENDING_CRLF bool "CRLF" config NEWLIB_STDIN_LINE_ENDING_LF @@ -406,7 +406,7 @@ choice CONSOLE_UART default CONSOLE_UART_DEFAULT help Select whether to use UART for console output (through stdout and stderr). - + - Default is to use UART0 on pins GPIO1(TX) and GPIO3(RX). - If "Custom" is selected, UART0 or UART1 can be chosen, and any pins can be selected. @@ -511,6 +511,14 @@ config ESP32_PANIC_GDBSTUB of the crash. endchoice +config ESP32_PANIC_CALLBACK + bool "Support registration of a user defined callback for the panic handler" + default y + help + Use xt_set_error_handler_callback() to register a custom callback. + The callback is called by the common error handler so catches exceptions, + panics and abort() calls. + config ESP32_DEBUG_OCDAWARE bool "Make exception and panic handlers JTAG/OCD aware" default y @@ -518,7 +526,6 @@ config ESP32_DEBUG_OCDAWARE The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and instead of panicking, have the debugger stop on the offending instruction. - config INT_WDT bool "Interrupt watchdog" default y @@ -550,7 +557,7 @@ config TASK_WDT help The Task Watchdog Timer can be used to make sure individual tasks are still running. Enabling this option will cause the Task Watchdog Timer to be - initialized automatically at startup. The Task Watchdog timer can be + initialized automatically at startup. The Task Watchdog timer can be initialized after startup as well (see Task Watchdog Timer API Reference) config TASK_WDT_PANIC @@ -656,7 +663,7 @@ choice ESP32_TIME_SYSCALL continue in deep sleep. Time will be reported at 1 microsecond resolution. This is the default, and the recommended option. - If only high-resolution timer is used, gettimeofday will - provide time at microsecond resolution. + provide time at microsecond resolution. Time will not be preserved when going into deep sleep mode. - If only RTC timer is used, timekeeping will continue in deep sleep, but time will be measured at 6.(6) microsecond @@ -700,7 +707,7 @@ config ESP32_RTC_CLK_CAL_CYCLES by the calibration routine. Higher numbers increase calibration precision, which may be important for applications which spend a lot of time in deep sleep. Lower numbers reduce startup time. - + When this option is set to 0, clock calibration will not be performed at startup, and approximate clock frequencies will be assumed: @@ -718,9 +725,9 @@ config ESP32_DEEP_SLEEP_WAKEUP_DELAY time to pass between power on and first read operation. By default, without any extra delay, this time is approximately 900us, although some flash chip types need more than that. - + By default extra delay is set to 2000us. When optimizing startup time - for applications which require it, this value may be reduced. + for applications which require it, this value may be reduced. If you are seeing "flash read err, 1000" message printed to the console after deep sleep reset, try increasing this value. @@ -918,7 +925,7 @@ config ESP32_WIFI_TX_BA_WIN default 6 help Set the size of WiFi Block Ack TX window. Generally a bigger value means higher throughput but - more memory. Most of time we should NOT change the default value unless special reason, e.g. + more memory. Most of time we should NOT change the default value unless special reason, e.g. test the maximum UDP TX throughput with iperf etc. For iperf test in shieldbox, the recommended value is 9~12. @@ -934,8 +941,8 @@ config ESP32_WIFI_RX_BA_WIN range 2 32 default 6 help - Set the size of WiFi Block Ack RX window. Generally a bigger value means higher throughput but - more memory. Most of time we should NOT change the default value unless special reason, e.g. + Set the size of WiFi Block Ack RX window. Generally a bigger value means higher throughput but + more memory. Most of time we should NOT change the default value unless special reason, e.g. test the maximum UDP RX throughput with iperf etc. For iperf test in shieldbox, the recommended value is 9~12. @@ -955,7 +962,7 @@ config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE help If this option is enabled, NVS will be initialized and calibration data will be loaded from there. PHY calibration will be skipped on deep sleep wakeup. If calibration data is not found, full calibration - will be performed and stored in NVS. Normally, only partial calibration will be performed. + will be performed and stored in NVS. Normally, only partial calibration will be performed. If this option is disabled, full calibration will be performed. If it's easy that your board calibrate bad data, choose 'n'. @@ -979,7 +986,7 @@ config ESP32_PHY_INIT_DATA_IN_PARTITION into the application binary. If unsure, choose 'n'. - + config ESP32_PHY_MAX_WIFI_TX_POWER int "Max WiFi TX power (dBm)" range 0 20 @@ -1005,7 +1012,7 @@ config PM_ENABLE This option has run-time overhead (increased interrupt latency, longer time to enter idle state), and it also reduces accuracy of RTOS ticks and timers used for timekeeping. - Enable this option if application uses power management APIs. + Enable this option if application uses power management APIs. config PM_DFS_INIT_AUTO bool "Enable dynamic frequency scaling (DFS) at startup" @@ -1042,7 +1049,7 @@ config PM_PROFILING This feature can be used to analyze which locks are preventing the chip from going into a lower power state, and see what time the chip spends in each power saving mode. This feature does incur some run-time - overhead, so should typically be disabled in production builds. + overhead, so should typically be disabled in production builds. config PM_TRACE bool "Enable debug tracing of PM using GPIOs" @@ -1055,6 +1062,6 @@ config PM_TRACE This feature is intended to be used when analyzing/debugging behavior of power management implementation, and should be kept disabled in applications. - + endmenu # "Power Management" diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 83bc657f1..7fc3ca1be 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -518,6 +518,19 @@ static void commonErrorHandler_dump(XtExcFrame *frame, int core_id) } +#if CONFIG_ESP32_PANIC_CALLBACK +/* + * Custom error handler callback registration. + */ +xt_error_handler_callback customErrorHandler = NULL; +xt_error_handler_callback xt_set_error_handler_callback(xt_error_handler_callback f) +{ + xt_error_handler_callback old = customErrorHandler; + customErrorHandler = f; + return old; +} +#endif //CONFIG_ESP32_PANIC_CALLBACK + /* We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the serial port and either jump to the gdb stub, halt the CPU or reboot. @@ -539,6 +552,14 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) } #endif //!CONFIG_FREERTOS_UNICORE +#if CONFIG_ESP32_PANIC_CALLBACK + if (customErrorHandler) { + disableAllWdts(); + customErrorHandler(frame, core_id, abort_called); + reconfigureAllWdts(); + } +#endif + #if CONFIG_ESP32_APPTRACE_ENABLE disableAllWdts(); #if CONFIG_SYSVIEW_ENABLE diff --git a/components/freertos/include/freertos/xtensa_api.h b/components/freertos/include/freertos/xtensa_api.h index 19630ce58..14b852fe6 100644 --- a/components/freertos/include/freertos/xtensa_api.h +++ b/components/freertos/include/freertos/xtensa_api.h @@ -39,6 +39,9 @@ typedef void (*xt_handler)(void *); /* Typedef for C-callable exception handler function */ typedef void (*xt_exc_handler)(XtExcFrame *); +/* Typedef for C-callable standard error handler callback */ +typedef void (*xt_error_handler_callback)(XtExcFrame *, int core_id, bool is_abort); + /* ------------------------------------------------------------------------------- @@ -60,11 +63,28 @@ typedef void (*xt_exc_handler)(XtExcFrame *); extern xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f); +/* +------------------------------------------------------------------------------- + Call this function to set a callback for the standard error handler. + The callback will be called by the commonErrorHandler on all errors. + + f - Callback function address, NULL to uninstall callback. + + The callback will be passed a pointer to the exception frame, which is created + on the stack of the thread that caused the exception, the core id and + a bool to signal if abort() has been called. + + The callback is called with watchdogs disabled. +------------------------------------------------------------------------------- +*/ +extern xt_error_handler_callback xt_set_error_handler_callback(xt_error_handler_callback f); + + /* ------------------------------------------------------------------------------- Call this function to set a handler for the specified interrupt. The handler will be installed on the core that calls this function. - + n - Interrupt number. f - Handler function address, NULL to uninstall handler. arg - Argument to be passed to handler. @@ -120,7 +140,7 @@ static inline void xt_set_intclear(unsigned int arg) /* ------------------------------------------------------------------------------- Call this function to get handler's argument for the specified interrupt. - + n - Interrupt number. ------------------------------------------------------------------------------- */