error_mcu: Move shutdown error message formatting to new error_mcu.py module

Create a new module to help format verbose mcu error messages.  Move
the shutdown message formatting to this module.  This moves the error
formatting out of the background thread and out of the critical
shutdown code path.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2024-06-15 12:13:35 -04:00
parent a19d64febd
commit 4ac283cc0e
3 changed files with 87 additions and 46 deletions

View file

@ -1,6 +1,6 @@
# Interface to Klipper micro-controller code
#
# Copyright (C) 2016-2023 Kevin O'Connor <kevin@koconnor.net>
# Copyright (C) 2016-2024 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, zlib, logging, math
@ -605,6 +605,7 @@ class MCU:
self._mcu_tick_stddev = 0.
self._mcu_tick_awake = 0.
# Register handlers
printer.load_object(config, "error_mcu")
printer.register_event_handler("klippy:firmware_restart",
self._firmware_restart)
printer.register_event_handler("klippy:mcu_identify",
@ -631,13 +632,13 @@ class MCU:
if clock is not None:
self._shutdown_clock = self.clock32_to_clock64(clock)
self._shutdown_msg = msg = params['static_string_id']
logging.info("MCU '%s' %s: %s\n%s\n%s", self._name, params['#name'],
event_type = params['#name']
self._printer.invoke_async_shutdown(
"MCU shutdown", {"reason": msg, "mcu": self._name,
"event_type": event_type})
logging.info("MCU '%s' %s: %s\n%s\n%s", self._name, event_type,
self._shutdown_msg, self._clocksync.dump_debug(),
self._serial.dump_debug())
prefix = "MCU '%s' shutdown: " % (self._name,)
if params['#name'] == 'is_shutdown':
prefix = "Previous MCU '%s' shutdown: " % (self._name,)
self._printer.invoke_async_shutdown(prefix + msg + error_help(msg))
def _handle_starting(self, params):
if not self._is_shutdown:
self._printer.invoke_async_shutdown("MCU '%s' spontaneous restart"
@ -1008,34 +1009,6 @@ class MCU:
self._get_status_info['last_stats'] = last_stats
return False, '%s: %s' % (self._name, stats)
Common_MCU_errors = {
("Timer too close",): """
This often indicates the host computer is overloaded. Check
for other processes consuming excessive CPU time, high swap
usage, disk errors, overheating, unstable voltage, or
similar system problems on the host computer.""",
("Missed scheduling of next ",): """
This is generally indicative of an intermittent
communication failure between micro-controller and host.""",
("ADC out of range",): """
This generally occurs when a heater temperature exceeds
its configured min_temp or max_temp.""",
("Rescheduled timer in the past", "Stepper too far in past"): """
This generally occurs when the micro-controller has been
requested to step at a rate higher than it is capable of
obtaining.""",
("Command request",): """
This generally occurs in response to an M112 G-Code command
or in response to an internal error in the host software.""",
}
def error_help(msg):
for prefixes, help_msg in Common_MCU_errors.items():
for prefix in prefixes:
if msg.startswith(prefix):
return help_msg
return ""
def add_printer_objects(config):
printer = config.get_printer()
reactor = printer.get_reactor()