diff --git a/cores/esp8266/cont_util.c b/cores/esp8266/cont_util.c index 84511dfff7..2d5d2b1eac 100644 --- a/cores/esp8266/cont_util.c +++ b/cores/esp8266/cont_util.c @@ -47,7 +47,8 @@ int ICACHE_RAM_ATTR cont_check(cont_t* cont) { return 0; } -int ICACHE_RAM_ATTR cont_get_free_stack(cont_t* cont) { +// No need for this to be in IRAM, not expected to be IRQ called +int cont_get_free_stack(cont_t* cont) { uint32_t *head = cont->stack; int freeWords = 0; diff --git a/cores/esp8266/core_esp8266_postmortem.c b/cores/esp8266/core_esp8266_postmortem.c index b78fbf0e5a..67ceac0127 100644 --- a/cores/esp8266/core_esp8266_postmortem.c +++ b/cores/esp8266/core_esp8266_postmortem.c @@ -62,32 +62,25 @@ extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack, extern void custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) __attribute__ ((weak, alias("__custom_crash_callback"))); -// Single, non-inlined copy of pgm_read_byte to save IRAM space (as this is not timing critical) -static char ICACHE_RAM_ATTR iram_read_byte (const char *addr) { - return pgm_read_byte(addr); -} - -// Required to output the s_panic_file, it's stored in PMEM -#define ets_puts_P(pstr) \ -{ \ - char c; \ - do { \ - c = iram_read_byte(pstr++); \ - if (c) ets_putc(c); \ - } while (c); \ -} -// Place these strings in .text because the SPI interface may be in bad shape during an exception. -#define ets_printf_P(str, ...) \ -{ \ - static const char istr[] ICACHE_RAM_ATTR = (str); \ - char mstr[sizeof(str)]; \ - for (size_t i=0; i < sizeof(str); i++) mstr[i] = iram_read_byte(&istr[i]); \ - ets_printf(mstr, ##__VA_ARGS__); \ +// Prints need to use our library function to allow for file and function +// to be safely accessed from flash. This function encapsulates snprintf() +// [which by definition will 0-terminate] and dumping to the UART +static void ets_printf_P(const char *str, ...) { + char destStr[160]; + char *c = destStr; + va_list argPtr; + va_start(argPtr, str); + vsnprintf(destStr, sizeof(destStr), str, argPtr); + va_end(argPtr); + while (*c) { + ets_putc(*(c++)); + } } void __wrap_system_restart_local() { register uint32_t sp asm("a1"); + uint32_t sp_dump = sp; if (gdb_present()) { /* When GDBStub is present, exceptions are handled by GDBStub, @@ -110,28 +103,24 @@ void __wrap_system_restart_local() { ets_install_putc1(&uart_write_char_d); if (s_panic_line) { - ets_printf_P("\nPanic "); - ets_puts_P(s_panic_file); // This is in PROGMEM, need special output because ets_printf can't handle ROM parameters - ets_printf_P(":%d %s", s_panic_line, s_panic_func); + ets_printf_P(PSTR("\nPanic %S:%d %S"), s_panic_file, s_panic_line, s_panic_func); if (s_panic_what) { - ets_printf_P(": Assertion '"); - ets_puts_P(s_panic_what); // This is also in PMEM - ets_printf_P("' failed."); + ets_printf_P(PSTR(": Assertion '%S' failed."), s_panic_what); } ets_putc('\n'); } else if (s_unhandled_exception) { - ets_printf_P("\nUnhandled exception: %s\n", s_unhandled_exception); + ets_printf_P(PSTR("\nUnhandled C++ exception: %S\n"), s_unhandled_exception); } else if (s_abort_called) { - ets_printf_P("\nAbort called\n"); + ets_printf_P(PSTR("\nAbort called\n")); } else if (rst_info.reason == REASON_EXCEPTION_RST) { - ets_printf_P("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n", + ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"), rst_info.exccause, rst_info.epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc); } else if (rst_info.reason == REASON_SOFT_WDT_RST) { - ets_printf_P("\nSoft WDT reset\n"); + ets_printf_P(PSTR("\nSoft WDT reset\n")); } uint32_t cont_stack_start = (uint32_t) &(g_pcont->stack); @@ -152,54 +141,53 @@ void __wrap_system_restart_local() { offset = 0x10; } - ets_printf_P("\n>>>stack>>>\n"); + ets_printf_P(PSTR("\n>>>stack>>>\n")); - if (sp > stack_thunk_get_stack_bot() && sp <= stack_thunk_get_stack_top()) { + if (sp_dump > stack_thunk_get_stack_bot() && sp_dump <= stack_thunk_get_stack_top()) { // BearSSL we dump the BSSL second stack and then reset SP back to the main cont stack - ets_printf_P("\nctx: bearssl \n"); - ets_printf_P("sp: %08x end: %08x offset: %04x\n", sp, stack_thunk_get_stack_top(), offset); - print_stack(sp + offset, stack_thunk_get_stack_top()); + ets_printf_P(PSTR("\nctx: bearssl\nsp: %08x end: %08x offset: %04x\n"), sp_dump, stack_thunk_get_stack_top(), offset); + print_stack(sp_dump + offset, stack_thunk_get_stack_top()); offset = 0; // No offset needed anymore, the exception info was stored in the bssl stack - sp = stack_thunk_get_cont_sp(); + sp_dump = stack_thunk_get_cont_sp(); } - if (sp > cont_stack_start && sp < cont_stack_end) { - ets_printf_P("\nctx: cont \n"); + if (sp_dump > cont_stack_start && sp_dump < cont_stack_end) { + ets_printf_P(PSTR("\nctx: cont\n")); stack_end = cont_stack_end; } else { - ets_printf_P("\nctx: sys \n"); + ets_printf_P(PSTR("\nctx: sys\n")); stack_end = 0x3fffffb0; // it's actually 0x3ffffff0, but the stuff below ets_run // is likely not really relevant to the crash } - ets_printf_P("sp: %08x end: %08x offset: %04x\n", sp, stack_end, offset); + ets_printf_P(PSTR("sp: %08x end: %08x offset: %04x\n"), sp_dump, stack_end, offset); - print_stack(sp + offset, stack_end); + print_stack(sp_dump + offset, stack_end); - ets_printf_P("<< -#define STRHELPER(x) #x -#define STR(x) STRHELPER(x) +#define __STRHELPER(x) #x +#define __STR(x) __STRHELPER(x) #ifdef __cplusplus extern "C++" @@ -111,7 +111,7 @@ namespace esp8266 { constexpr int coreVersionMajor () { - return conststr::parseNthInteger(STR(ARDUINO_ESP8266_GIT_DESC), 0); + return conststr::parseNthInteger(__STR(ARDUINO_ESP8266_GIT_DESC), 0); } /* @@ -120,7 +120,7 @@ int coreVersionMajor () constexpr int coreVersionMinor () { - return conststr::parseNthInteger(STR(ARDUINO_ESP8266_GIT_DESC), 1); + return conststr::parseNthInteger(__STR(ARDUINO_ESP8266_GIT_DESC), 1); } /* @@ -129,7 +129,7 @@ int coreVersionMinor () constexpr int coreVersionRevision () { - return conststr::parseNthInteger(STR(ARDUINO_ESP8266_GIT_DESC), 2); + return conststr::parseNthInteger(__STR(ARDUINO_ESP8266_GIT_DESC), 2); } /* @@ -139,7 +139,7 @@ int coreVersionRevision () constexpr int coreVersionSubRevision () { - return conststr::parseNthInteger(STR(ARDUINO_ESP8266_GIT_DESC), 3); + return conststr::parseNthInteger(__STR(ARDUINO_ESP8266_GIT_DESC), 3); } /* diff --git a/cores/esp8266/umm_malloc/umm_malloc.c b/cores/esp8266/umm_malloc/umm_malloc.c index c86142b27e..46b8578927 100644 --- a/cores/esp8266/umm_malloc/umm_malloc.c +++ b/cores/esp8266/umm_malloc/umm_malloc.c @@ -1202,8 +1202,9 @@ static unsigned short int umm_assimilate_down( unsigned short int c, unsigned sh } /* ------------------------------------------------------------------------- */ - -void umm_init( void ) { +/* This function called only one time during OS startup after flash is */ +/* enabled. No need to keep it in IRAM. */ +void ICACHE_FLASH_ATTR umm_init( void ) { /* init heap pointer and size, and memset it to 0 */ umm_heap = (umm_block *)UMM_MALLOC_CFG__HEAP_ADDR; umm_numblocks = (UMM_MALLOC_CFG__HEAP_SIZE / sizeof(umm_block));