Reset and Boot Sequence — MicroPython latest documentation (original) (raw)

A device running MicroPython follows a particular boot sequence to start up and initialise itself after a reset.

Hard reset

Booting from hard reset is what happens when a board is first powered up, a cold boot. This is a complete reset of the MCU hardware.

The MicroPython port code initialises all essential hardware (including embedded clocks and power regulators, internal serial UART, etc), and then starts the MicroPython environment. Existing RTCconfiguration may be retained after a hard reset, but all other hardware state is cleared.

The same hard reset boot sequence can be triggered by a number of events such as:

The details of hardware-specific reset triggers depend on the port and associated hardware. The machine.reset_cause() function can be used to further determine the cause of a reset.

Soft Reset

When MicroPython is already running, it’s possible to trigger a soft reset bytyping Ctrl-D in the REPL or executingmachine.soft_reset().

A soft reset clears the Python interpreter, frees all Python memory, and starts the MicroPython environment again.

State which is cleared by a soft reset includes:

Some system state remains the same after a soft reset, including:

Boot Sequence

When MicroPython boots following either a hard or soft reset, it follows this boot sequence in order:

_boot.py

This is an internal script frozen into the MicroPython firmware. It is provided by MicroPython on many ports to do essential initialisation.

For example, on most ports _boot.py will detect the first boot of a new device and format the internal flash filesystem ready for use.

Unless you’re creating a custom MicroPython build or adding a new port then you probably don’t need to worry about _boot.py. It’s best not to change the contents unless you really know what you’re doing.

boot.py

A file named boot.py can be copied to the board’s internal filesystem using mpremote.

If boot.py is found then it is executed. You can add code in boot.py to perform custom one-off initialisation (for example, to configure the board’s hardware).

A common practice is to configure a board’s network connection in boot.py so that it’s always available after reset for use with the REPL,mpremote, etc.

Warning

boot.py should always exit and not run indefinitely.

Depending on the port, some hardware initialisation is delayed until afterboot.py exits. This includes initialising USB on the stm32 port and all ports which support machine.USBDevice. On these ports, output printed from boot.py may not be visible on the built-in USB serial port until after boot.py finishes running.

The purpose of this late initialisation is so that it’s possible to pre-configure particular hardware in boot.py, and then have it start with the correct configuration.

Note

It is sometimes simpler to not have a boot.py file and place any initialisation code at the top of main.py instead.

main.py

Similar to boot.py, a file named main.py can be copied to the board’s internal filesystem. If found then it is executed next in the startup process.

main.py is for any Python code that you want to run each time your device starts.

Some tips for main.py usage:

Following a normal Exception or main() exiting, reset the board.

Following a non-Exception error such as KeyboardInterrupt (Ctrl-C),

this code will drop to a REPL. Place machine.reset() in a finally

block to always reset, instead.

machine.reset()
Otherwise MicroPython will drop to the REPL following any crash or if main exits (see below).

Interactive Interpreter (REPL)

If main.py is not found, or if main.py exits, then The MicroPython Interactive Interpreter Mode (aka REPL)will start immediately.

Note

Even if main.py contains an infinite loop, typing Ctrl-C on the REPL serial port will inject a KeyboardInterrupt. If no exception handler catches it then main.py will exit and the REPL will start.

Any global variables that were set in boot.py and main.py will still be set in the global context of the REPL.

The REPL continues executing until Python code triggers a hard or soft reset.

Soft Bricking (failure to boot)

It is rare but possible for MicroPython to become unresponsive during startup, a state sometimes called “soft bricked”. For example:

Rest assured, recovery is possible!

KeyboardInterrupt

In many cases, opening the REPL serial port and typing Ctrl-C will injectKeyboardInterrupt and may cause the running script to exit and a REPL to start. From the REPL, you can use os.remove() to remove the misbehaving Python file:

import os os.remove('main.py')

To confirm which files are still present in the internal filesystem:

Safe Mode and Factory Reset

If you’re unable to easily access the REPL then you may need to perform one of two processes:

  1. “Safe mode” boot, which skips boot.py and main.py and immediately starts a REPL, allowing you to clean up. This is only supported on some ports.
  2. Factory Reset to erase the entire contents of the flash filesystem. This may also be necessary if the internal flash filesystem has become corrupted somehow.

The specific process(es) are different on each port:

For ports without specific instructions linked above, the factory reset process involves erasing the board’s entire flash and then flashing MicroPython again from scratch. Usually this will involve the same tool(s) that were originally used to install MicroPython. Consult the installation docs for your board, or ask on the GitHub Discussions if you’re not sure.

Warning

Re-flashing the MicroPython firmware without erasing the entire flash first will usually not recover from soft bricking, as a firmware update usually preserves the contents of the filesystem.