From d46d9d5c21e21267979e8d5f6ffef84d86f2a53e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 13 Feb 2023 21:29:57 -0500 Subject: [PATCH] shorten safe mode messages; improve message printing; fix CIRCUITPY_SAFEMODE_PY=0 --- locale/circuitpython.pot | 64 +++++++-------- py/circuitpy_defns.mk | 6 +- shared-bindings/supervisor/Runtime.c | 5 +- shared-bindings/supervisor/SafeModeReason.c | 10 +-- shared-bindings/supervisor/__init__.c | 2 +- supervisor/shared/safe_mode.c | 90 ++++++++++----------- 6 files changed, 88 insertions(+), 89 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 960625e949..e6948de330 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -31,14 +31,20 @@ msgstr "" #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" #: supervisor/shared/safe_mode.c msgid "" "\n" -"To exit, reset the board without requesting safe mode." +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c @@ -536,10 +542,6 @@ msgstr "" msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -588,7 +590,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -790,10 +792,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "" @@ -832,10 +830,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -1003,6 +997,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fault detected by hardware." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1088,6 +1086,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1993,15 +2000,7 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c @@ -2013,10 +2012,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -2162,6 +2158,10 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2367,10 +2367,6 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "" - #: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h #: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h #: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -2385,7 +2381,7 @@ msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up." +msgid "You pressed the BOOT button at start up" msgstr "" #: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index eaf78d3688..9de0e5a804 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -525,12 +525,16 @@ $(filter $(SRC_PATTERNS), \ qrio/PixelPolicy.c \ qrio/QRInfo.c \ supervisor/RunReason.c \ - supervisor/SafeModeReason.c \ supervisor/StatusBar.c \ wifi/AuthMode.c \ wifi/Packet.c \ ) +ifeq ($(CIRCUITPY_SAFEMODE_PY),1) +SRC_BINDINGS_ENUMS += \ + supervisor/SafeModeReason.c +endif + SRC_BINDINGS_ENUMS += \ util.c diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index c9c47a638d..db3d8d1e4d 100644 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -117,7 +117,10 @@ MP_PROPERTY_GETTER(supervisor_runtime_run_reason_obj, (mp_obj_t)&supervisor_runtime_get_run_reason_obj); //| safe_mode_reason: SafeModeReason -//| """Why CircuitPython went into safe mode this particular time (read-only).""" +//| """Why CircuitPython went into safe mode this particular time (read-only). +//| +//| **Limitations**: Raises ``NotImplementedError`` on builds that do not implement ``safemode.py``. +//| """ STATIC mp_obj_t supervisor_runtime_get_safe_mode_reason(mp_obj_t self) { #if CIRCUITPY_SAFEMODE_PY return cp_enum_find(&supervisor_safe_mode_reason_type, get_safe_mode()); diff --git a/shared-bindings/supervisor/SafeModeReason.c b/shared-bindings/supervisor/SafeModeReason.c index 9a253596f3..180b7a1530 100644 --- a/shared-bindings/supervisor/SafeModeReason.c +++ b/shared-bindings/supervisor/SafeModeReason.c @@ -31,7 +31,6 @@ // Reuse the non-Python safe_mode_t enum #include "supervisor/shared/safe_mode.h" -#if CIRCUITPY_SAFEMODE_PY MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, NONE, SAFE_MODE_NONE); MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, BROWNOUT, SAFE_MODE_BROWNOUT); // alphabetical from here down @@ -50,16 +49,16 @@ MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USB_TOO_MANY MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USB_TOO_MANY_INTERFACE_NAMES, SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES); MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USER, SAFE_MODE_USER); MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, WATCHDOG, SAFE_MODE_WATCHDOG); -#endif //| class SafeModeReason: -//| """The reason that CircuitPython went into safe mode.""" +//| """The reason that CircuitPython went into safe mode. +//| +//| **Limitations**: Class not available on builds that do not implement ``safemode.py``. +//| """ //| MAKE_ENUM_MAP(supervisor_safe_mode_reason) { - #if CIRCUITPY_SAFEMODE_PY - //| NONE: object //| """CircuitPython is not in safe mode.""" //| @@ -146,7 +145,6 @@ MAKE_ENUM_MAP(supervisor_safe_mode_reason) { //| """An internal watchdog timer expired.""" //| MAKE_ENUM_MAP_ENTRY(safe_mode_reason, WATCHDOG), - #endif }; STATIC MP_DEFINE_CONST_DICT(supervisor_safe_mode_reason_locals_dict, supervisor_safe_mode_reason_locals_table); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index 850931ceac..491cac2f17 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -339,7 +339,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { #if CIRCUITPY_SAFEMODE_PY { MP_ROM_QSTR(MP_QSTR_SafeModeReason), MP_ROM_PTR(&supervisor_safe_mode_reason_type) }, #else - { MP_ROM_QSTR(MP_QSTR_SafeModeReason), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_SafeModeReason), MP_ROM_NONE }, #endif { MP_ROM_QSTR(MP_QSTR_set_next_code_file), MP_ROM_PTR(&supervisor_set_next_code_file_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&supervisor_ticks_ms_obj) }, diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 0032337a75..5112b17ebf 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -145,8 +145,7 @@ void print_safe_mode_message(safe_mode_t reason) { return; } - serial_write("\r\n"); - serial_write_compressed(translate("You are in safe mode because:\n")); + serial_write_compressed(translate("\nYou are in safe mode because:\n")); const compressed_string_t *message = NULL; @@ -154,29 +153,31 @@ void print_safe_mode_message(safe_mode_t reason) { switch (reason) { case SAFE_MODE_BROWNOUT: - message = translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY)."); + message = translate("The power dipped. Make sure you are providing enough power."); break; case SAFE_MODE_USER: #if defined(BOARD_USER_SAFE_MODE_ACTION) message = BOARD_USER_SAFE_MODE_ACTION; #elif defined(CIRCUITPY_BOOT_BUTTON) - message = translate("You pressed the BOOT button at start up."); + message = translate("You pressed the BOOT button at start up"); #else message = translate("You pressed the reset button during boot."); #endif - serial_write_compressed(message); - message = translate("\nTo exit, reset the board without requesting safe mode."); - // The final piece is printed below. break; case SAFE_MODE_NO_CIRCUITPY: message = translate("CIRCUITPY drive could not be found or created."); break; case SAFE_MODE_PROGRAMMATIC: - message = translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode."); + message = translate("The `microcontroller` module was used to boot into safe mode."); break; + #if CIRCUITPY_SAFEMODE_PY case SAFE_MODE_SAFEMODE_PY_ERROR: message = translate("Error in safemode.py."); break; + #endif + case SAFE_MODE_STACK_OVERFLOW: + message = translate("Heap was corrupted because the stack was too small. Increase stack size."); + break; case SAFE_MODE_USB_TOO_MANY_ENDPOINTS: message = translate("USB devices need more endpoints than are available."); break; @@ -184,7 +185,7 @@ void print_safe_mode_message(safe_mode_t reason) { message = translate("USB devices specify too many interface names."); break; case SAFE_MODE_USB_BOOT_DEVICE_NOT_INTERFACE_ZERO: - message = translate("Boot device must be first device (interface #0)."); + message = translate("Boot device must be first (interface #0)."); break; case SAFE_MODE_WATCHDOG: message = translate("Internal watchdog timer expired."); @@ -194,44 +195,41 @@ void print_safe_mode_message(safe_mode_t reason) { } if (message) { + // Non-crash safe mode. serial_write_compressed(message); - serial_write("\r\n"); - return; + } else { + // Something worse happened. + serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); + switch (reason) { + case SAFE_MODE_GC_ALLOC_OUTSIDE_VM: + message = translate("Heap allocation when VM not running."); + break; + case SAFE_MODE_FLASH_WRITE_FAIL: + message = translate("Failed to write internal flash."); + break; + case SAFE_MODE_HARD_FAULT: + message = translate("Fault detected by hardware."); + break; + case SAFE_MODE_INTERRUPT_ERROR: + message = translate("Interrupt error."); + break; + case SAFE_MODE_NLR_JUMP_FAIL: + message = translate("NLR jump failed. Likely memory corruption."); + break; + case SAFE_MODE_NO_HEAP: + message = translate("Unable to allocate the heap."); + break; + case SAFE_MODE_SDK_FATAL_ERROR: + message = translate("Third-party firmware fatal error."); + break; + default: + message = translate("Unknown reason."); + break; + } + serial_write_compressed(message); + serial_write_compressed(translate("\nPlease file an issue with your program at https://github.com/adafruit/circuitpython/issues.")); } - // Something worse happened. - - serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); - - switch (reason) { - case SAFE_MODE_GC_ALLOC_OUTSIDE_VM: - message = translate("Attempted heap allocation when VM not running."); - break; - case SAFE_MODE_FLASH_WRITE_FAIL: - message = translate("Failed to write internal flash."); - break; - case SAFE_MODE_HARD_FAULT: - message = translate("Crash into the HardFault_Handler."); - break; - case SAFE_MODE_INTERRUPT_ERROR: - message = translate("Interrupt error."); - break; - case SAFE_MODE_NLR_JUMP_FAIL: - message = translate("NLR jump failed. Likely memory corruption."); - break; - case SAFE_MODE_NO_HEAP: - message = translate("CircuitPython was unable to allocate the heap."); - break; - case SAFE_MODE_SDK_FATAL_ERROR: - message = translate("Third-party firmware fatal error."); - break; - case SAFE_MODE_STACK_OVERFLOW: - message = translate("The CircuitPython heap was corrupted because the stack was too small.\nIncrease the stack size if you know how. If not:"); - break; - default: - message = translate("Unknown reason."); - break; - } - serial_write_compressed(message); - serial_write_compressed(translate("\nPlease file an issue with the contents of your CIRCUITPY drive at \nhttps://github.com/adafruit/circuitpython/issues\n")); + // Always tell user how to get out of safe mode. + serial_write_compressed(translate("\nPress reset to exit safe mode.\n")); }