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.
This commit is contained in:
Yuri D'Elia 2021-06-12 13:37:20 +02:00
parent f7dc8dcaef
commit bd57e00448
13 changed files with 126 additions and 14 deletions

View file

@ -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

View file

@ -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".

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;