Skip to content

Implement safemode.py #7577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,26 @@ Behavior
- Adds a safe mode that does not run user code after a hard crash or brown out. This makes it
possible to fix code that causes nasty crashes by making it available through mass storage after
the crash. A reset (the button) is needed after it's fixed to get back into normal mode.
- Safe mode may be handled programmatically by providing a ``safemode.py``.
``safemode.py`` is run if the board has reset due to entering safe mode, unless the safe mode
initiated by the user by pressing button(s).
USB is not available so nothing can be printed.
``safemode.py`` can determine why the safe mode occurred
using ``supervisor.runtime.safe_mode_reason``, and take appropriate action. For instance,
if a hard crash occurred, ``safemode.py`` may do a ``microcontroller.reset()``
to automatically restart despite the crash.
If the battery is low, but is being charged, ``safemode.py`` may put the board in deep sleep
for a while. Or it may simply reset, and have ``code.py`` check the voltage and do the sleep.
- RGB status LED indicating CircuitPython state.
- One green flash - code completed without error.
- Two red flashes - code ended due to an exception.
- Three yellow flashes - safe mode. May be due to CircuitPython internal error.
- Re-runs ``code.py`` or other main file after file system writes by a workflow. (Disable with
``supervisor.disable_autoreload()``)
- Autoreload is disabled while the REPL is active.
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
``main.txt``
- Boot is one of these: ``boot.py``, ``boot.txt``
- ``code.py`` may also be named``code.txt``, ``main.py``, or ``main.txt``.
- ``boot.py`` may also be named ``boot.txt``.
- ``safemode.py`` may also be named ``safemode.txt``.

API
~~~
Expand Down
159 changes: 78 additions & 81 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +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"
"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
Expand Down Expand Up @@ -85,7 +97,7 @@ msgstr ""
#: ports/raspberrypi/common-hal/alarm/__init__.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c
#: ports/stm/common-hal/rtc/RTC.c
#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""

Expand Down Expand Up @@ -530,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 ""
Expand Down Expand Up @@ -582,20 +590,13 @@ 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
msgid "Both RX and TX required for flow control"
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
#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h
msgid "Both buttons were pressed at start up.\n"
msgstr ""

#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
msgid "Both pins must support hardware interrupts"
msgstr ""
Expand Down Expand Up @@ -661,12 +662,6 @@ msgstr ""
msgid "Bus pin %d is already in use"
msgstr ""

#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h
#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h
#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h
msgid "Button A was pressed at start up.\n"
msgstr ""

#: shared-bindings/_bleio/UUID.c
msgid "Byte buffer must be 16 bytes."
msgstr ""
Expand Down Expand Up @@ -797,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 ""
Expand Down Expand Up @@ -839,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 ""
Expand Down Expand Up @@ -934,6 +921,10 @@ msgstr ""
msgid "Error in regex"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Error in safemode.py."
msgstr ""

#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c
msgid "Error: Failure to bind"
msgstr ""
Expand Down Expand Up @@ -1007,7 +998,7 @@ msgid "Failed to write internal flash."
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Fatal error."
msgid "Fault detected by hardware."
msgstr ""

#: py/moduerrno.c
Expand Down Expand Up @@ -1095,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 ""
Expand Down Expand Up @@ -1209,6 +1209,10 @@ msgstr ""
msgid "Internal watchdog timer expired."
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Interrupt error."
msgstr ""

#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c
msgid "Invalid %q"
msgstr ""
Expand Down Expand Up @@ -1257,10 +1261,6 @@ msgstr ""
msgid "Invalid format chunk size"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Invalid memory access."
msgstr ""

#: ports/espressif/common-hal/wifi/Radio.c
msgid "Invalid multicast MAC address"
msgstr ""
Expand Down Expand Up @@ -1549,10 +1549,6 @@ msgstr ""
msgid "No timer available"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Nordic system firmware failure assertion."
msgstr ""

#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Nordic system firmware out of memory"
msgstr ""
Expand Down Expand Up @@ -2004,53 +2000,19 @@ msgid "Temperature read timed out"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "The BOOT button was pressed at start up.\n"
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 ""

#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h
msgid "The SW38 button was pressed at start up.\n"
msgstr ""

#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h
msgid "The VOLUME button was pressed at start up.\n"
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
msgid "The above exception was the direct cause of the following exception:"
msgstr ""

#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h
msgid "The central button was pressed at start up.\n"
msgstr ""

#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h
msgid "The left button was pressed at start up.\n"
msgstr ""

#: shared-bindings/rgbmatrix/RGBMatrix.c
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
Expand All @@ -2069,6 +2031,10 @@ msgstr ""
msgid "The sample's signedness does not match the mixer's"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "Third-party firmware fatal error."
msgstr ""

#: shared-module/imagecapture/ParallelImageCapture.c
msgid "This microcontroller does not support continuous capture."
msgstr ""
Expand Down Expand Up @@ -2101,10 +2067,6 @@ msgstr ""
msgid "Timeout is too long: Maximum timeout length is %d seconds"
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "To exit, please reset the board without requesting safe mode."
msgstr ""

#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample"
msgstr ""
Expand Down Expand Up @@ -2196,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 ""
Expand Down Expand Up @@ -2401,13 +2367,44 @@ msgstr ""
msgid "Writes not supported on Characteristic"
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
#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h
msgid "You pressed both buttons at start up."
msgstr ""

#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h
#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h
#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h
msgid "You pressed button A at start up."
msgstr ""

#: supervisor/shared/safe_mode.c
msgid "You are in safe mode because:\n"
msgid "You pressed the BOOT button at start up"
msgstr ""

#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h
msgid "You pressed the SW38 button at start up."
msgstr ""

#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h
msgid "You pressed the VOLUME button at start up."
msgstr ""

#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h
#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h
msgid "You pressed the central button at start up."
msgstr ""

#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h
msgid "You pressed the left button at start up."
msgstr ""

#: supervisor/shared/safe_mode.c
msgid ""
"You pressed the reset button during boot. Press again to exit safe mode."
msgid "You pressed the reset button during boot."
msgstr ""

#: py/objtype.c
Expand Down
Loading