diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index ea27caff6..0b2943b06 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -932,11 +932,11 @@ void dcode_9125() void dcode_20() { if(code_seen('E')) - xfdump_full_dump_and_reset(); + xfdump_full_dump_and_reset(SP); else { unsigned long ts = _millis(); - xfdump_dump(); + xfdump_dump(SP); ts = _millis() - ts; DBG(_N("dump completed in %lums\n"), ts); } @@ -971,7 +971,7 @@ void dcode_22() bool emergency_serial_dump = false; -void serial_dump_and_reset(dump_crash_reason reason) +void serial_dump_and_reset(uint16_t sp, dump_crash_reason reason) { // we're being called from a live state, so shut off interrupts and heaters cli(); @@ -982,7 +982,9 @@ void serial_dump_and_reset(dump_crash_reason reason) // this function can also be called from within a corrupted state, so not use // printf family of functions that use the heap or grow the stack. SERIAL_ECHOLNPGM("D23 - emergency serial dump"); - SERIAL_ECHOPGM("reason: "); + SERIAL_ECHOPGM("exception: "); + SERIAL_ECHO(sp); + SERIAL_ECHO(" "); SERIAL_ECHOLN((unsigned)reason); // set WDT long enough to allow writing the entire stream diff --git a/Firmware/Dcodes.h b/Firmware/Dcodes.h index c4b470e4b..477a58470 100644 --- a/Firmware/Dcodes.h +++ b/Firmware/Dcodes.h @@ -38,7 +38,7 @@ extern void dcode_22(); //D22 - Clear crash dump state #ifdef EMERGENCY_SERIAL_DUMP #include "xflash_dump.h" extern bool emergency_serial_dump; -extern void serial_dump_and_reset(dump_crash_reason); +extern void serial_dump_and_reset(uint16_t sp, dump_crash_reason); #endif #ifdef HEATBED_ANALYSIS diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 1b50daaf7..acf73ab83 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1716,15 +1716,15 @@ void setup() } -static inline void crash_and_burn(dump_crash_reason reason) +static inline void crash_and_burn(uint16_t sp, dump_crash_reason reason) { WRITE(BEEPER, HIGH); eeprom_update_byte((uint8_t*)EEPROM_FW_CRASH_FLAG, (uint8_t)reason); #ifdef EMERGENCY_DUMP - xfdump_full_dump_and_reset(reason); + xfdump_full_dump_and_reset(sp, reason); #elif defined(EMERGENCY_SERIAL_DUMP) if(emergency_serial_dump) - serial_dump_and_reset(reason); + serial_dump_and_reset(sp, reason); #endif softReset(); } @@ -1733,18 +1733,18 @@ static inline void crash_and_burn(dump_crash_reason reason) #ifdef WATCHDOG ISR(WDT_vect) { - crash_and_burn(dump_crash_reason::watchdog); + crash_and_burn(SP, dump_crash_reason::watchdog); } #endif ISR(BADISR_vect) { - crash_and_burn(dump_crash_reason::bad_isr); + crash_and_burn(SP, dump_crash_reason::bad_isr); } #endif //EMERGENCY_HANDLERS void stack_error() { - crash_and_burn(dump_crash_reason::stack_error); + crash_and_burn(SP, dump_crash_reason::stack_error); } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index c2c148830..dd3d3f5ce 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -1807,7 +1807,7 @@ static void lcd_preheat_menu() static void lcd_dump_memory() { lcd_beeper_quick_feedback(); - xfdump_dump(); + xfdump_dump(SP); lcd_return_to_status(); } #endif //MENU_DUMP @@ -1816,7 +1816,7 @@ static void lcd_dump_memory() static void lcd_serial_dump() { - serial_dump_and_reset(dump_crash_reason::manual); + serial_dump_and_reset(SP, dump_crash_reason::manual); } #endif //MENU_SERIAL_DUMP diff --git a/Firmware/xflash_dump.cpp b/Firmware/xflash_dump.cpp index 8b4ab9955..4c9aca42d 100644 --- a/Firmware/xflash_dump.cpp +++ b/Firmware/xflash_dump.cpp @@ -68,12 +68,13 @@ static void xfdump_dump_core(dump_header_t& hdr, uint32_t addr, uint8_t* buf, ui } -void xfdump_dump() +void xfdump_dump(uint16_t sp) { dump_header_t buf; buf.magic = DUMP_MAGIC; buf.regs_present = false; buf.crash_reason = (uint8_t)dump_crash_reason::manual; + buf.sp = sp; // write sram only xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data.sram), @@ -81,12 +82,13 @@ void xfdump_dump() } -void xfdump_full_dump_and_reset(dump_crash_reason reason) +void xfdump_full_dump_and_reset(uint16_t sp, dump_crash_reason reason) { dump_header_t buf; buf.magic = DUMP_MAGIC; buf.regs_present = true; buf.crash_reason = (uint8_t)reason; + buf.sp = sp; // disable interrupts for a cleaner register dump cli(); diff --git a/Firmware/xflash_dump.h b/Firmware/xflash_dump.h index 8866b1ec5..c9a82c667 100644 --- a/Firmware/xflash_dump.h +++ b/Firmware/xflash_dump.h @@ -11,12 +11,13 @@ enum class dump_crash_reason : uint8_t }; #ifdef XFLASH_DUMP -void xfdump_reset(); // reset XFLASH dump state -void xfdump_dump(); // create a new SRAM memory dump +void xfdump_reset(); // reset XFLASH dump state +void xfdump_dump(uint16_t sp); // create a new SRAM memory dump // return true if a dump is present, save type in "reason" if provided bool xfdump_check_state(dump_crash_reason* reason = NULL); // create a new dump containing registers and SRAM, then reset -void xfdump_full_dump_and_reset(dump_crash_reason crash = dump_crash_reason::manual); +void xfdump_full_dump_and_reset( + uint16_t sp, dump_crash_reason crash = dump_crash_reason::manual); #endif diff --git a/Firmware/xflash_layout.h b/Firmware/xflash_layout.h index 31f67b7d6..0e533494c 100644 --- a/Firmware/xflash_layout.h +++ b/Firmware/xflash_layout.h @@ -21,6 +21,7 @@ struct dump_header_t uint8_t regs_present; // true when the lower segment containing registers is present uint8_t crash_reason; // uses values from dump_crash_source + uint16_t sp; // SP closest to the crash location }; struct dump_data_t