Browse Source

Implement an online crash dumper for MK2.5 boards

When XFLASH is not available, allow users to request _online_ crash
dumps by using D23 (since these require active user cooperation).

Once enabled, instead of just rebooting, dump memory directly to
the serial.

As similarly done with EMERGENCY_DUMP, we have two features that can be
enabled:

EMERGENCY_SERIAL_DUMP: enables dumping on crash after being requested
MENU_SERIAL_DUMP: allow triggering the same manually through the support
menu.
Yuri D'Elia 2 years ago
parent
commit
bd57e00448

+ 28 - 0
Firmware/Dcodes.cpp

@@ -965,3 +965,31 @@ void dcode_22()
     }
 }
 #endif
+
+#ifdef EMERGENCY_SERIAL_DUMP
+#include "xflash_dump.h"
+
+bool emergency_serial_dump = false;
+
+void serial_dump_and_reset(dump_crash_reason reason)
+{
+    // we're being called from a live state, so shut off interrupts and heaters
+    cli();
+    wdt_enable(WDTO_15MS);
+    disable_heater();
+
+    // 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_ECHOLN((unsigned)reason);
+
+    // disable interrupts from now on to avoid wdt while dumping
+    wdt_disable();
+    print_mem(0, RAMEND+1, dcode_mem_t::sram);
+    SERIAL_ECHOLNRPGM(MSG_OK);
+
+    // reset soon
+    softReset();
+}
+#endif

+ 6 - 0
Firmware/Dcodes.h

@@ -35,6 +35,12 @@ extern void dcode_21(); //D21 - Print crash dump to serial
 extern void dcode_22(); //D22 - Clear crash dump state
 #endif
 
+#ifdef EMERGENCY_SERIAL_DUMP
+#include "xflash_dump.h"
+extern bool emergency_serial_dump;
+extern void serial_dump_and_reset(dump_crash_reason);
+#endif
+
 #ifdef HEATBED_ANALYSIS
 extern void dcode_80(); //D80 - Bed check. This command will log data to SD card file "mesh.txt".
 extern void dcode_81(); //D81 - Bed analysis. This command will log data to SD card file "wldsd.txt".

+ 25 - 3
Firmware/Marlin_main.cpp

@@ -1679,18 +1679,24 @@ void setup()
   KEEPALIVE_STATE(NOT_BUSY);
 #ifdef WATCHDOG
   wdt_enable(WDTO_4S);
-#ifdef EMERGENCY_DUMP
+#ifdef EMERGENCY_HANDLERS
   WDTCSR |= (1 << WDIE);
-#endif //EMERGENCY_DUMP
+#endif //EMERGENCY_HANDLERS
 #endif //WATCHDOG
 }
 
-#if defined(WATCHDOG) && defined(EMERGENCY_DUMP)
+#if defined(WATCHDOG) && defined(EMERGENCY_HANDLERS)
 ISR(WDT_vect)
 {
     WRITE(BEEPER, 1);
+#ifdef EMERGENCY_DUMP
     eeprom_update_byte((uint8_t*)EEPROM_CRASH_ACKNOWLEDGED, 0);
     xfdump_full_dump_and_reset(dump_crash_reason::watchdog);
+#else //EMERGENCY_SERIAL_DUMP
+    if(emergency_serial_dump)
+        serial_dump_and_reset(dump_crash_reason::watchdog);
+    softReset();
+#endif
 }
 #endif
 
@@ -9292,6 +9298,22 @@ Sigma_Exit:
         dcode_22();
         break;
     };
+#endif //XFLASH_DUMP
+
+#ifdef EMERGENCY_SERIAL_DUMP
+    /*!
+    ### D23 - Request emergency dump on serial
+    On boards without offline dump support, request online dumps to the serial port on firmware faults.
+    When online dumps are enabled, the FW will dump memory on the serial before resetting.
+    #### Usage
+
+     D23 [R]
+    #### Parameters
+    - `R` - Disable online dumps.
+    */
+    case 23: {
+        emergency_serial_dump = !code_seen('R');
+    };
 #endif
 
 #ifdef HEATBED_ANALYSIS

+ 13 - 0
Firmware/config.h

@@ -76,4 +76,17 @@
 #error "MENU_DUMP and EMERGENCY_DUMP require XFLASH_DUMP"
 #endif
 
+// Support for serial dumps is mutually exclusive with XFLASH_DUMP features
+#if defined(EMERGENCY_DUMP) && defined(EMERGENCY_SERIAL_DUMP)
+#error "EMERGENCY_DUMP and EMERGENCY_SERIAL_DUMP are mutually exclusive"
+#endif
+#if defined(MENU_DUMP) && defined(MENU_SERIAL_DUMP)
+#error "MENU_DUMP and MENU_SERIAL_DUMP are mutually exclusive"
+#endif
+
+// Reduce internal duplication
+#if defined(EMERGENCY_DUMP) || defined(EMERGENCY_SERIAL_DUMP)
+#define EMERGENCY_HANDLERS
+#endif
+
 #endif //_CONFIG_H

+ 24 - 4
Firmware/ultralcd.cpp

@@ -1812,8 +1812,16 @@ static void lcd_dump_memory()
     lcd_return_to_status();
 }
 #endif //MENU_DUMP
+#ifdef MENU_SERIAL_DUMP
+#include "Dcodes.h"
 
-#if defined(WATCHDOG) && defined(EMERGENCY_DUMP) && defined(DEBUG_BUILD)
+static void lcd_serial_dump()
+{
+    serial_dump_and_reset(dump_crash_reason::manual);
+}
+#endif //MENU_SERIAL_DUMP
+
+#if defined(WATCHDOG) && defined(DEBUG_BUILD) && defined(EMERGENCY_HANDLERS)
 static void lcd_wdr_crash()
 {
     while (1);
@@ -2015,8 +2023,12 @@ static void lcd_support_menu()
 #ifdef MENU_DUMP
     MENU_ITEM_FUNCTION_P(_i("Dump memory"), lcd_dump_memory);
 #endif //MENU_DUMP
+#ifdef MENU_SERIAL_DUMP
+    if (emergency_serial_dump)
+        MENU_ITEM_FUNCTION_P(_i("Dump to serial"), lcd_serial_dump);
+#endif
 #ifdef DEBUG_BUILD
-#if defined(WATCHDOG) && defined(EMERGENCY_DUMP)
+#if defined(WATCHDOG) && defined(EMERGENCY_HANDLERS)
     MENU_ITEM_FUNCTION_P(PSTR("WDR crash"), lcd_wdr_crash);
 #endif
   MENU_ITEM_SUBMENU_P(PSTR("Debug"), lcd_menu_debug);////MSG_DEBUG c=18
@@ -6716,14 +6728,22 @@ void stack_error() {
     eeprom_update_byte((uint8_t*)EEPROM_CRASH_ACKNOWLEDGED, 0);
     xfdump_full_dump_and_reset(dump_crash_reason::stack_error);
 }
-#else
+#else //EMERGENCY_DUMP
+#ifdef EMERGENCY_SERIAL_DUMP
+#include "Dcodes.h"
+#endif
+
 void stack_error() {
+#ifdef EMERGENCY_SERIAL_DUMP
+    if (emergency_serial_dump)
+        serial_dump_and_reset(dump_crash_reason::stack_error);
+#endif
 	Sound_MakeCustom(1000,0,true);
 	lcd_display_message_fullscreen_P(_i("Error - static memory has been overwritten"));////MSG_STACK_ERROR c=20 r=4
 	//err_triggered = 1;
 	 while (1) delay_keep_alive(1000);
 }
-#endif
+#endif //EMERGENCY_DUMP
 
 #ifdef DEBUG_STEPPER_TIMER_MISSED
 bool stepper_timer_overflow_state = false;

+ 4 - 0
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -119,6 +119,10 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 #define FARM_DEFAULT_SAFETYTIMER_TIME_ms (45*60*1000ul)
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define PAT9125

+ 4 - 0
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -120,6 +120,10 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 #define FARM_DEFAULT_SAFETYTIMER_TIME_ms (45*60*1000ul)
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define PAT9125

+ 4 - 0
Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h

@@ -119,6 +119,10 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 #define FARM_DEFAULT_SAFETYTIMER_TIME_ms (45*60*1000ul)
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define IR_SENSOR

+ 4 - 0
Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h

@@ -120,6 +120,10 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 #define FARM_DEFAULT_SAFETYTIMER_TIME_ms (45*60*1000ul)
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define IR_SENSOR

+ 4 - 0
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -144,6 +144,10 @@
 //#define MENU_DUMP       // enable "Memory dump" in Settings menu
 //#define EMERGENCY_DUMP  // trigger crash on stack corruption and WDR
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define PAT9125

+ 4 - 0
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -146,6 +146,10 @@
 //#define MENU_DUMP       // enable "Memory dump" in Settings menu
 //#define EMERGENCY_DUMP  // trigger crash on stack corruption and WDR
 
+// Online crash dumper
+//#define EMERGENCY_SERIAL_DUMP   // Request dump via serial on stack corruption and WDR
+//#define MENU_SERIAL_DUMP        // Enable "Memory dump" in Settings menu
+
 // Filament sensor
 #define FILAMENT_SENSOR
 #define IR_SENSOR

+ 4 - 5
Firmware/xflash_dump.h

@@ -1,10 +1,6 @@
 // XFLASH dumper
 #pragma once
 #include "xflash_layout.h"
-#ifdef XFLASH_DUMP
-
-void xfdump_reset();        // reset XFLASH dump state
-void xfdump_dump();         // create a new SRAM memory dump
 
 enum class dump_crash_reason : uint8_t
 {
@@ -13,10 +9,13 @@ enum class dump_crash_reason : uint8_t
     watchdog,
 };
 
+#ifdef XFLASH_DUMP
+void xfdump_reset();        // reset XFLASH dump state
+void xfdump_dump();         // 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);
-
 #endif

+ 2 - 2
Firmware/xyzcal.cpp

@@ -163,9 +163,9 @@ void xyzcal_meassure_leave(void)
 	ENABLE_STEPPER_DRIVER_INTERRUPT();
 #ifdef WATCHDOG
 	wdt_enable(WDTO_4S);
-#ifdef EMERGENCY_DUMP
+#ifdef EMERGENCY_HANDLERS
 	WDTCSR |= (1 << WDIE);
-#endif //EMERGENCY_DUMP
+#endif //EMERGENCY_HANDLERS
 #endif //WATCHDOG
 	sm4_stop_cb = 0;
 	sm4_update_pos_cb = 0;