Soft Reset via Serial or post-kill button click (#21652)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
fedetony 2021-04-24 09:53:52 +02:00 committed by Scott Lahteine
parent 27a26fcfeb
commit c39c17c1b5
29 changed files with 97 additions and 27 deletions

View File

@ -3976,3 +3976,9 @@
* a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash. * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash.
*/ */
//#define POSTMORTEM_DEBUGGING //#define POSTMORTEM_DEBUGGING
/**
* Software Reset options
*/
//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller
//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL

View File

@ -58,6 +58,15 @@ void HAL_init() {
#endif #endif
} }
void HAL_reboot() {
#if ENABLED(USE_WATCHDOG)
while (1) { /* run out the watchdog */ }
#else
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
resetFunc(); // Jump to address 0
#endif
}
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#include "../../sd/SdFatUtil.h" #include "../../sd/SdFatUtil.h"

View File

@ -135,7 +135,7 @@ void HAL_init();
inline void HAL_clear_reset_source() { MCUSR = 0; } inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; } inline uint8_t HAL_get_reset_source() { return MCUSR; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
#if GCC_VERSION <= 50000 #if GCC_VERSION <= 50000
#pragma GCC diagnostic push #pragma GCC diagnostic push

View File

@ -77,6 +77,8 @@ uint8_t HAL_get_reset_source() {
} }
} }
void HAL_reboot() { rstc_start_software_reset(RSTC); }
void _delay_ms(const int delay_ms) { void _delay_ms(const int delay_ms) {
// Todo: port for Due? // Todo: port for Due?
delay(delay_ms); delay(delay_ms);

View File

@ -113,7 +113,7 @@ void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason uint8_t HAL_get_reset_source(); // get reset reason
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
// //
// ADC // ADC

View File

@ -141,6 +141,8 @@ void HAL_clear_reset_source() { }
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); } uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
void HAL_reboot() { ESP.restart(); }
void _delay_ms(int delay_ms) { delay(delay_ms); } void _delay_ms(int delay_ms) { delay(delay_ms); }
// return free memory between end of heap (or end bss) and whatever is current // return free memory between end of heap (or end bss) and whatever is current

View File

@ -101,7 +101,7 @@ void HAL_clear_reset_source();
// reset reason // reset reason
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
void _delay_ms(int delay); void _delay_ms(int delay);

View File

@ -73,4 +73,6 @@ void HAL_pwm_init() {
} }
void HAL_reboot() { /* Reset the application state and GPIO */ }
#endif // __PLAT_LINUX__ #endif // __PLAT_LINUX__

View File

@ -107,7 +107,7 @@ uint16_t HAL_adc_get_result();
inline void HAL_clear_reset_source(void) {} inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; } inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot(); // Reset the application state and GPIO
/* ---------------- Delay in cycles */ /* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) { FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {

View File

@ -67,7 +67,7 @@ void flashFirmware(const int16_t) {
delay(500); // Give OS time to disconnect delay(500); // Give OS time to disconnect
USB_Connect(false); // USB clear connection USB_Connect(false); // USB clear connection
delay(1000); // Give OS time to notice delay(1000); // Give OS time to notice
NVIC_SystemReset(); HAL_reboot();
} }
void HAL_clear_reset_source(void) { void HAL_clear_reset_source(void) {
@ -81,4 +81,6 @@ uint8_t HAL_get_reset_source(void) {
return RST_POWER_ON; return RST_POWER_ON;
} }
void HAL_reboot() { NVIC_SystemReset(); }
#endif // TARGET_LPC1768 #endif // TARGET_LPC1768

View File

@ -218,4 +218,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255,
void HAL_clear_reset_source(void); void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void); uint8_t HAL_get_reset_source(void);
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();

View File

@ -436,6 +436,8 @@ uint8_t HAL_get_reset_source() {
} }
#pragma pop_macro("WDT") #pragma pop_macro("WDT")
void HAL_reboot() { NVIC_SystemReset(); }
extern "C" { extern "C" {
void * _sbrk(int incr); void * _sbrk(int incr);

View File

@ -109,7 +109,7 @@ typedef int8_t pin_t;
void HAL_clear_reset_source(); // clear reset reason void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason uint8_t HAL_get_reset_source(); // get reset reason
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
// //
// ADC // ADC

View File

@ -133,6 +133,8 @@ uint8_t HAL_get_reset_source() {
; ;
} }
void HAL_reboot() { NVIC_SystemReset(); }
void _delay_ms(const int delay_ms) { delay(delay_ms); } void _delay_ms(const int delay_ms) { delay(delay_ms); }
extern "C" { extern "C" {
@ -147,8 +149,8 @@ extern "C" {
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); } void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
uint16_t HAL_adc_get_result() { return HAL_adc_result; } uint16_t HAL_adc_get_result() { return HAL_adc_result; }
// Reset the system (to initiate a firmware flash) // Reset the system to initiate a firmware flash
void flashFirmware(const int16_t) { NVIC_SystemReset(); } void flashFirmware(const int16_t) { HAL_reboot(); }
// Maple Compatibility // Maple Compatibility
volatile uint32_t systick_uptime_millis = 0; volatile uint32_t systick_uptime_millis = 0;

View File

@ -144,7 +144,7 @@ void HAL_clear_reset_source();
// Reset reason // Reset reason
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
void _delay_ms(const int delay); void _delay_ms(const int delay);

View File

@ -453,6 +453,8 @@ void analogWrite(pin_t pin, int pwm_val8) {
analogWrite(uint8_t(pin), pwm_val8); analogWrite(uint8_t(pin), pwm_val8);
} }
void flashFirmware(const int16_t) { nvic_sys_reset(); } void HAL_reboot() { nvic_sys_reset(); }
void flashFirmware(const int16_t) { HAL_reboot(); }
#endif // __STM32F1__ #endif // __STM32F1__

View File

@ -207,7 +207,7 @@ void HAL_clear_reset_source();
// Reset reason // Reset reason
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
void _delay_ms(const int delay); void _delay_ms(const int delay);

View File

@ -78,6 +78,8 @@ uint8_t HAL_get_reset_source() {
return 0; return 0;
} }
void HAL_reboot() { _reboot_Teensyduino_(); }
extern "C" { extern "C" {
extern char __bss_end; extern char __bss_end;
extern char __heap_start; extern char __heap_start;

View File

@ -34,7 +34,6 @@
#include "fastio.h" #include "fastio.h"
#include "watchdog.h" #include "watchdog.h"
#include <stdint.h> #include <stdint.h>
#define ST7920_DELAY_1 DELAY_NS(600) #define ST7920_DELAY_1 DELAY_NS(600)
@ -93,7 +92,7 @@ void HAL_clear_reset_source();
// Get the reason for the reset // Get the reason for the reset
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }

View File

@ -86,6 +86,8 @@ uint8_t HAL_get_reset_source() {
return 0; return 0;
} }
void HAL_reboot() { _reboot_Teensyduino_(); }
extern "C" { extern "C" {
extern char __bss_end; extern char __bss_end;
extern char __heap_start; extern char __heap_start;

View File

@ -101,7 +101,7 @@ void HAL_clear_reset_source();
// Reset reason // Reset reason
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
inline void HAL_reboot() {} // reboot the board or restart the bootloader void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }

View File

@ -120,6 +120,8 @@ uint8_t HAL_get_reset_source() {
return 0; return 0;
} }
void HAL_reboot() { _reboot_Teensyduino_(); }
#define __bss_end _ebss #define __bss_end _ebss
extern "C" { extern "C" {

View File

@ -121,6 +121,8 @@ void HAL_clear_reset_source();
// Reset reason // Reset reason
uint8_t HAL_get_reset_source(); uint8_t HAL_get_reset_source();
void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); } FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
#if GCC_VERSION <= 50000 #if GCC_VERSION <= 50000

View File

@ -863,20 +863,22 @@ void minkill(const bool steppers_off/*=false*/) {
TERN_(HAS_SUICIDE, suicide()); TERN_(HAS_SUICIDE, suicide());
#if HAS_KILL #if EITHER(HAS_KILL, SOFT_RESET_ON_KILL)
// Wait for kill to be released // Wait for both KILL and ENC to be released
while (kill_state()) watchdog_refresh(); while (TERN0(HAS_KILL, !kill_state()) || TERN0(SOFT_RESET_ON_KILL, !ui.button_pressed()))
watchdog_refresh();
// Wait for kill to be pressed // Wait for either KILL or ENC press
while (!kill_state()) watchdog_refresh(); while (TERN1(HAS_KILL, kill_state()) && TERN1(SOFT_RESET_ON_KILL, ui.button_pressed()))
watchdog_refresh();
void (*resetFunc)() = 0; // Declare resetFunc() at address 0 // Reboot the board
resetFunc(); // Jump to address 0 HAL_reboot();
#else #else
for (;;) watchdog_refresh(); // Wait for reset for (;;) watchdog_refresh(); // Wait for RESET button or power-cycle
#endif #endif
} }

View File

@ -41,6 +41,8 @@ extern bool wait_for_user, wait_for_heatup;
void quickresume_stepper(); void quickresume_stepper();
#endif #endif
void HAL_reboot();
class EmergencyParser { class EmergencyParser {
public: public:
@ -62,6 +64,10 @@ public:
EP_R, EP_R0, EP_R00, EP_GRBL_RESUME, EP_R, EP_R0, EP_R00, EP_GRBL_RESUME,
EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE, EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE,
#endif #endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
EP_ctrl,
EP_K, EP_KI, EP_KIL, EP_KILL,
#endif
EP_IGNORE // to '\n' EP_IGNORE // to '\n'
}; };
@ -89,6 +95,10 @@ public:
case 'P': state = EP_P; break; case 'P': state = EP_P; break;
case 'R': state = EP_R; break; case 'R': state = EP_R; break;
#endif #endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case '^': state = EP_ctrl; break;
case 'K': state = EP_K; break;
#endif
default: state = EP_IGNORE; default: state = EP_IGNORE;
} }
break; break;
@ -121,6 +131,13 @@ public:
case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break; case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break;
#endif #endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case EP_ctrl: state = (c == 'X') ? EP_KILL : EP_IGNORE; break;
case EP_K: state = (c == 'I') ? EP_KI : EP_IGNORE; break;
case EP_KI: state = (c == 'L') ? EP_KIL : EP_IGNORE; break;
case EP_KIL: state = (c == 'L') ? EP_KILL : EP_IGNORE; break;
#endif
case EP_M: case EP_M:
switch (c) { switch (c) {
case ' ': break; case ' ': break;
@ -189,6 +206,9 @@ public:
case EP_GRBL_PAUSE: quickpause_stepper(); break; case EP_GRBL_PAUSE: quickpause_stepper(); break;
case EP_GRBL_RESUME: quickresume_stepper(); break; case EP_GRBL_RESUME: quickresume_stepper(); break;
#endif #endif
#if ENABLED(SOFT_RESET_VIA_SERIAL)
case EP_KILL: HAL_reboot(); break;
#endif
default: break; default: break;
} }
state = EP_RESET; state = EP_RESET;

View File

@ -30,6 +30,7 @@
#include "../HAL/shared/eeprom_if.h" #include "../HAL/shared/eeprom_if.h"
#include "../HAL/shared/Delay.h" #include "../HAL/shared/Delay.h"
#include "../sd/cardreader.h" #include "../sd/cardreader.h"
#include "../MarlinCore.h" // for kill
extern void dump_delay_accuracy_check(); extern void dump_delay_accuracy_check();
@ -44,12 +45,16 @@
switch (dcode) { switch (dcode) {
case -1: case -1:
for (;;); // forever for (;;) { /* loop forever (watchdog reset) */ }
case 0: case 0:
HAL_reboot(); HAL_reboot();
break; break;
case 10:
kill(PSTR("D10"), PSTR("KILL TEST"), parser.seen('P'));
break;
case 1: { case 1: {
// Zero or pattern-fill the EEPROM data // Zero or pattern-fill the EEPROM data
#if ENABLED(EEPROM_SETTINGS) #if ENABLED(EEPROM_SETTINGS)

View File

@ -2208,12 +2208,19 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
#endif #endif
/** /**
* emergency-command parser * Emergency Command Parser
*/ */
#if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON) #if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON)
#error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)." #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
#endif #endif
/**
* Software Reset on Kill option
*/
#if ENABLED(SOFT_RESET_ON_KILL) && !BUTTON_EXISTS(ENC)
#error "An encoder button is required or SOFT_RESET_ON_KILL will reset the printer without notice!"
#endif
/** /**
* I2C bus * I2C bus
*/ */

View File

@ -39,7 +39,7 @@
#include "tft_io/touch_calibration.h" #include "tft_io/touch_calibration.h"
#endif #endif
#if EITHER(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY) #if ANY(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY, SOFT_RESET_ON_KILL)
#define HAS_ENCODER_ACTION 1 #define HAS_ENCODER_ACTION 1
#endif #endif

View File

@ -45,7 +45,7 @@ opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER ADAPTIVE_FAN_SLOWING NO
Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \ Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \
HOST_KEEPALIVE_FEATURE HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT \ HOST_KEEPALIVE_FEATURE HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT \
LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES \ LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES \
SDSUPPORT SDCARD_SORT_ALPHA AUTO_REPORT_SD_STATUS EMERGENCY_PARSER SDSUPPORT SDCARD_SORT_ALPHA AUTO_REPORT_SD_STATUS EMERGENCY_PARSER SOFT_RESET_ON_KILL SOFT_RESET_VIA_SERIAL
exec_test $1 $2 "Re-ARM with NOZZLE_AS_PROBE and many features." "$3" exec_test $1 $2 "Re-ARM with NOZZLE_AS_PROBE and many features." "$3"
# clean up # clean up