Browse Source

Report crash also in MK2.5, fix stack_error abuse

Rename EEPROM_CRASH_ACKNOWLEDGED to EEPROM_FW_CRASH_FLAG.

Use EEPROM_FW_CRASH_FLAG to always set the last crash reason, which
simplifies handling between the online/offline variants.

Make stack_error safe, by setting the flag and restarting immediately,
so that the error can be shown after restart.
Yuri D'Elia 3 years ago
parent
commit
e28301f391
3 changed files with 67 additions and 44 deletions
  1. 55 27
      Firmware/Marlin_main.cpp
  2. 3 3
      Firmware/eeprom.h
  3. 9 14
      Firmware/ultralcd.cpp

+ 55 - 27
Firmware/Marlin_main.cpp

@@ -995,6 +995,55 @@ void list_sec_lang_from_external_flash()
 #endif //(LANG_MODE != 0)
 
 
+static void fw_crash_init()
+{
+#ifdef XFLASH_DUMP
+    dump_crash_reason crash_reason;
+    if(xfdump_check_state(&crash_reason))
+    {
+        // always signal to the host that a dump is available for retrieval
+        puts_P(_N("// action:dump_available"));
+
+#ifdef EMERGENCY_DUMP
+        if(crash_reason != dump_crash_reason::manual &&
+           eeprom_read_byte((uint8_t*)EEPROM_FW_CRASH_FLAG) != 0xFF)
+        {
+            lcd_show_fullscreen_message_and_wait_P(
+                    _i("!!!FIRMWARE CRASH!!!\n"
+                       "Debug data available for analysis. "
+                       "Contact support to submit details."));
+        }
+#endif
+    }
+#else //XFLASH_DUMP
+    dump_crash_reason crash_reason = (dump_crash_reason)eeprom_read_byte((uint8_t*)EEPROM_FW_CRASH_FLAG);
+    if(crash_reason != dump_crash_reason::manual && (uint8_t)crash_reason != 0xFF)
+    {
+        lcd_beeper_quick_feedback();
+        lcd_clear();
+
+        lcd_puts_P(_i("!!!FIRMWARE CRASH!!!\nCrash reason:\n"));
+        switch(crash_reason)
+        {
+        case dump_crash_reason::stack_error:
+            lcd_puts_P(_i("Static memory has\nbeen overwritten"));
+            break;
+        case dump_crash_reason::watchdog:
+            lcd_puts_P(_i("Watchdog timeout"));
+            break;
+        default:
+            lcd_print((uint8_t)crash_reason);
+            break;
+        }
+        lcd_wait_for_click();
+    }
+#endif //XFLASH_DUMP
+
+    // prevent crash prompts to reappear once acknowledged
+    eeprom_update_byte((uint8_t*)EEPROM_FW_CRASH_FLAG, 0xFF);
+}
+
+
 static void xflash_err_msg()
 {
 	lcd_clear();
@@ -1610,29 +1659,8 @@ void setup()
 	if (tmc2130_home_enabled == 0xff) tmc2130_home_enabled = 0;
 #endif //TMC2130
 
-#ifdef XFLASH_DUMP
-    {
-        dump_crash_reason crash_reason;
-        if(xfdump_check_state(&crash_reason))
-        {
-            // always signal to the host that a dump is available for retrieval
-            puts_P(_N("// action:dump_available"));
-
-#ifdef EMERGENCY_DUMP
-            if(crash_reason != dump_crash_reason::manual &&
-               eeprom_read_byte((uint8_t*)EEPROM_CRASH_ACKNOWLEDGED) != 1)
-            {
-                // prevent the prompt to reappear once acknowledged
-                eeprom_update_byte((uint8_t*)EEPROM_CRASH_ACKNOWLEDGED, 1);
-                lcd_show_fullscreen_message_and_wait_P(
-                        _i("!!!FIRMWARE CRASH!!!\n"
-                           "Debug data available for analysis. "
-                           "Contact support to submit details."));
-            }
-#endif
-        }
-    }
-#endif
+    // report crash failures
+    fw_crash_init();
 
 #ifdef UVLO_SUPPORT
   if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) != 0) { //previous print was terminated by UVLO
@@ -1688,15 +1716,15 @@ void setup()
 #if defined(WATCHDOG) && defined(EMERGENCY_HANDLERS)
 ISR(WDT_vect)
 {
-    WRITE(BEEPER, 1);
+    WRITE(BEEPER, HIGH);
+    eeprom_update_byte((uint8_t*)EEPROM_FW_CRASH_FLAG, (uint8_t)dump_crash_reason::watchdog);
 #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
+#elif defined(EMERGENCY_SERIAL_DUMP)
     if(emergency_serial_dump)
         serial_dump_and_reset(dump_crash_reason::watchdog);
-    softReset();
 #endif
+    softReset();
 }
 #endif
 

+ 3 - 3
Firmware/eeprom.h

@@ -327,7 +327,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
 | 0x0D05 3333		| uint32_t	| EEPROM_JOB_ID							| ???			| 00 00 00 00h			| Job ID used by host software						| D3 only		| D3 Ax0d05 C4
 | 0x0D04 3332		| uint8_t	| EEPROM_ECOOL_ENABLE					| ffh 255		| ^						| Disable extruder motor scaling for non-farm print	| LCD menu		| D3 Ax0d04 C1
 | ^					| ^			| ^										| 2ah 42		| ^						| Enable extruder motor scaling for non-farm print	| ^				| D3 Ax0d04 C1
-| 0x0D03 3321		| uint8_t	| EEPROM_CRASH_ACKNOWLEDGED				| 01h 1			| ff/00					| Disable crash report after first acknowledgment	| D21/D22		| D3 Ax0d03 C1
+| 0x0D03 3321		| uint8_t	| EEPROM_FW_CRASH_FLAG					| 01h 1			| ff/00					| Last FW crash reason (dump_crash_reason)			| D21/D22		| D3 Ax0d03 C1
 
 | Address begin		| Bit/Type 	| Name 									| Valid values	| Default/FactoryReset	| Description 										| Gcode/Function| Debug code
 | :--:				| :--: 		| :--: 									| :--:			| :--:					| :--:												| :--:			| :--:
@@ -542,10 +542,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 #define EEPROM_JOB_ID (EEPROM_UVLO_TRAVEL_ACCELL-4) //uint32_t
 
 #define EEPROM_ECOOL_ENABLE (EEPROM_JOB_ID-1) // uint8_t
-#define EEPROM_CRASH_ACKNOWLEDGED (EEPROM_ECOOL_ENABLE-1) // uint8_t
+#define EEPROM_FW_CRASH_FLAG (EEPROM_ECOOL_ENABLE-1) // uint8_t
 
 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
-#define EEPROM_LAST_ITEM EEPROM_CRASH_ACKNOWLEDGED
+#define EEPROM_LAST_ITEM EEPROM_FW_CRASH_FLAG
 // !!!!!
 // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
 // !!!!!

+ 9 - 14
Firmware/ultralcd.cpp

@@ -6720,30 +6720,25 @@ static void lcd_main_menu()
 
 }
 
+
 #ifdef EMERGENCY_DUMP
 #include "xflash_dump.h"
-
-void stack_error() {
-    WRITE(BEEPER, HIGH);
-    eeprom_update_byte((uint8_t*)EEPROM_CRASH_ACKNOWLEDGED, 0);
-    xfdump_full_dump_and_reset(dump_crash_reason::stack_error);
-}
-#else //EMERGENCY_DUMP
-#ifdef EMERGENCY_SERIAL_DUMP
+#elif defined(EMERGENCY_SERIAL_DUMP)
 #include "Dcodes.h"
 #endif
 
 void stack_error() {
-#ifdef EMERGENCY_SERIAL_DUMP
+    WRITE(BEEPER, HIGH);
+    eeprom_update_byte((uint8_t*)EEPROM_FW_CRASH_FLAG, (uint8_t)dump_crash_reason::stack_error);
+#ifdef EMERGENCY_DUMP
+    xfdump_full_dump_and_reset(dump_crash_reason::stack_error);
+#elif defined(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);
+    softReset();
 }
-#endif //EMERGENCY_DUMP
+
 
 #ifdef DEBUG_STEPPER_TIMER_MISSED
 bool stepper_timer_overflow_state = false;