Skip to main content

MPFLASH

pypi version python versions Downloads

mpflash is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more attached microcontrollers.

This tool was initially created to be used in a CI/CD pipeline to automate the process of downloading and flashing MicroPython firmware to multiple boards, but it has been extend with a TUI to be used for manual downloadig, flashing and development.

The interactive prompts use rich-inquirer for a modern, keyboard-navigable TUI experience that integrates visually with Rich terminal output. Selection lists, fuzzy search, and multi-select are all rendered with Rich styling. A standard terminal (VT100-compatible) is required; redirected or non-interactive stdin (e.g. CI pipelines) will automatically skip interactive prompts.

mpflash has been tested on:

  • OS: Windows x64, Linux X64, and macOS.
  • Micropython (hardware) ports:
    • rp2, using .uf2, using filecopy
    • samd, using .uf2, using filecopy
    • esp32, using .bin, using esptool,
    • esp8266, using .bin, using esptool
    • stm32, using .dfu, using pydfu (also in Windows)
    • nrf, using .uf2, using filecopy

Not yet implemented: alif, mimxrt, psoc-edge, renesas-ra, zephyr Not planned: cc3200, pic16bit

Features

  • List connected boards — show firmware details for all attached boards in a table or JSON format.
  • Download firmware — fetch MicroPython firmware for a version, matched to a specified board or your attached board(s).
  • Flash boards — flash one or all connected boards with a specific firmware or version, downloading it if needed.
  • Flash via a debug probe (pyOCD) — program stm32, rp2 and samd targets over SWD/JTAG using a CMSIS-DAP / ST-Link / J-Link probe with mpflash flash --method pyocd. CMSIS packs for missing targets are installed automatically. Install with pip install "mpflash[pyocd]".
  • Build firmware locally (mpbuild) — use mpflash flash --build to compile MicroPython with mpbuild (requires Docker) right before flashing.
  • Pluggable flash & bootloader backends — flashing and bootloader activation are selectable, port-agnostic plugins, and third-party backends can register their own. List them with mpflash plugins.
  • Filesystem erase over serial--erase wipes the MicroPython filesystem via its block device.
  • Filesystem format over serial--format recreates an empty MicroPython filesystem after flashing, keeping the same filesystem type (VfsLfs2 or VfsFat).
  • Probe & target info — inspect probes and supported targets with mpflash list-probes, mpflash pyocd-info and mpflash pyocd-targets.

Installation

To install mpflash, you can use either of the following commands:

  • uv tool install mpflash
  • pipx install mpflash
  • pip install mpflash

Basic usage

You can use mpflash to perform various operations on your MicroPython boards. Here is an example of basic usage:

Command Description
mpflash list List the connected board(s) including their firmware details
mpflash flash Flash the latest stable firmware to the connected board(s), downloading the firmware if needed
mpflash download Download the MicroPython firmware(s) for the connected board(s)
mpflash format Reformat the filesystem of the connected board(s) without flashing new firmware
mpflash erase Erase the filesystem of the connected board(s) and reboot, without flashing new firmware

Listing connected boards:
mpflash list will list all connected boards in a table , including their serial port, family, board name, CPU, version and build number. Options are available to list the boards in a json format, or to filter the list by serial port or board type.

Flashing boards with new firmware:
mpflash flash will flash the latest stable firmware to all connected boards, downloading the firmware if needed. It will try to determine the current micropython borad and variant, download the firmware if needed, and flash the correct firmware to each board.

Common options are:

  • --version to specify the version of the firmware to flash, defaults to the latest stable version.
  • --serial to specify the serial port(s) to flash, defaults to all connected boards.
  • --board to specify which firmware to flash to a single board
  • --variant to specify a specific variant of the board

Downloading firmware: mpflash download will download the latest stable firmware for all connected boards, or a specific board if specified. It will download the firmware from the official MicroPython website and save it in your Downloads/firmware directory.
When a board is specified for which multiple variants are available, all variants will be downloaded.

Common options are:

  • --version to specify the version of the firmware to download, defaults to the latest stable version. (e.g. stable, preview, x.y.z)
  • --serial to specify the serial port(s) to flash, defaults to all connected boards.
  • --board to specify which firmware to flash to a single board

Setting the Firmware Files and Database Location

You can override the default location for firmware files and the MPFlash database by setting the MPFLASH_FIRMWARE environment variable. For example, in a Bash shell:

export MPFLASH_FIRMWARE="/path/to/custom/firmware"

When this variable is set, mpflash will use that location to store firmware files and estabish it's database.

You can also override the firmware and database location for a single invocation using the global --dir option:

mpflash --dir "/path/to/custom/firmware" download
mpflash --dir "/path/to/custom/firmware" flash --board ESP32_GENERIC --serial COM3

The --dir option takes precedence over the MPFLASH_FIRMWARE environment variable.

Selecting or ignoring specific serial ports

You can use the --serial option to select a specific serial port(s) to flash,
Or you can use the --ignore option to ignore a specific serial port(s).

Either option can be specified multiple times, can be globs (e.g. COM*) or exact port names (e.g. /dev/ttyUSB0). To permenently ignore a port, you can set the MPFLASH_IGNORE environment variable to a space-separated list of serial ports or globs.

In addition there is a --bluetooth option to simplify ignoring bluetooth ports, where the default is to ignore bluetooth ports.

--serial,--serial-port      -s      SERIALPORT  Serial port(s) (or globs) to list. [default: *]                                                                                                                                                                           > > --ignore                    -i      SERIALPORT  Serial port(s) (or globs) to ignore. Defaults to MPFLASH_IGNORE.                                                                                                                                                          │
--bluetooth/--no-bluetooth  -b/-nb              Include bluetooth ports in the list [default: no-bluetooth] 

Distinguishing similar boards

The mpflash list command will list all connected boards, but sometimes you have multiple boards of the same type connected. To help you identify the boards, you can add a board_info.toml file to the top/default folder for the board. This file can contain a description of the board, which will be shown in the list and json output.

description = "Blue Norwegian actuator"

If you want the board to be ignored by mpflash, no matter which serial port it is connected to, you can add the following to the board_info.toml file:

description = "Blue Norwegian actuator"
[mpflash]
ignore = true

Linux permissions to access usb devices

In order to flash the firmware to the board, you need to have the correct permissions to access the USB devices. On Windows this will not be an issue, but on Linux you can use udev rules to give non-root users access to the USB devices. See the stm32_permissions documentation for more information.

Use MPFlash in your own project

MPFlash can be used as a library in your own project. mpflash is used in micropython-stubber to download and flash the firmware to the connected boards.

⚠️ API Changes: The worklist module API has been completely refactored in v1.25.1+. Legacy functions have been removed. See API Documentation for the new interface.

# Modern API example
from mpflash.flash.worklist import create_worklist
from mpflash.connected import get_connected_comports

# Get connected boards and create worklist
boards = get_connected_comports()
tasks = create_worklist("1.25.0", connected_comports=boards)

# Process tasks
for task in tasks:
    if task.is_valid:
        print(f"{task.board.serialport} -> {task.firmware_version}")

The interface is documented in:

Detailed usage

You can list the connected boards using the following command:

$> mpflash list
                                               Connected boards
┏━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━┓
┃ Serial  ┃Family       ┃Port  ┃Board                                      ┃CPU     ┃Version          ┃build ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━┩
│ COM21   │micropython  │rp2   │RPI_PICO                                   │RP2040  │v1.23.0-preview    236 │
│                            │Raspberry Pi Pico with RP2040                                             │
│ COM23   │micropython  │rp2   │RPI_PICO_W                                 │RP2040  │v1.23.0-preview    176 │
│                            │Raspberry Pi Pico W with RP2040                                           │
│ COM9    │micropython  │rp2   │ARDUINO_NANO_RP2040_CONNECT                │RP2040  │v1.23.0-preview    341 │
│                            │Arduino Nano RP2040 Connect with RP2040                                   │
└─────────┴─────────────┴──────┴───────────────────────────────────────────┴────────┴─────────────────┴──────┘

Download the firmware

To download the MicroPython firmware for some boards, use the following command:

  • mpflash download download the latest stable firmware for all connected boards
  • mpflash download --version preview download the current preview for all connected boards
  • mpflash download --board ESP8266_GENERIC --board SEEED_WIO_TERMINAL download these specific boards
  • mpflash download --version ? --board ? prompt to select a specific version and board to download

These will try to download the prebuilt MicroPython firmware for the boards from https://micropython.org/download/ and save it in your downloads folder in the firmware directory. The stable version (default) is determined based on the most recent published release, other options are --version stable, --version preview and --version x.y.z to download the latest stable, preview or version x.y.z respectively.

By default the firmware will be downloaded to your OS's preferred Downloads/firmware folder. You can specify a different directory using:

  • the global --dir option on the command line: mpflash --dir /path/to/firmware download
  • the MPFLASH_FIRMWARE environment variable (applies to all commands): export MPFLASH_FIRMWARE="/path/to/firmware"

The --dir option takes precedence over the MPFLASH_FIRMWARE environment variable.

The directory structure will be something like this:

Downloads/firmware
|   firmware.jsonl
+---esp8266
|       ESP8266_GENERIC-FLASH_1M-v1.22.2.bin
|       ESP8266_GENERIC-FLASH_512K-v1.22.2.bin
|       ESP8266_GENERIC-OTA-v1.22.2.bin
|       ESP8266_GENERIC-v1.22.2.bin
\---samd
        SEEED_WIO_TERMINAL-v1.22.2.uf2

Flashing the firmware

After you have downloaded a firmware you can flash the firmware to a board using the following command: mpflash flash This will (try to) autodetect the connected boards, and determine the correct firmware to flash to each board.

  • mpflash flash will flash the latest stable firmware to all connected boards. If you have a board withouth a running micropython version, you will need to specify the board and the serial port to flash.
  • mpflash flash --serial ? --board ? will prompt to select a specific serial port and board to flash. (the firmware must be dowloaded earlier)

In order to flash the firmware some boards need to be put in bootloader mode, this is done automatically by mpflash where possible and supported by the boards hardware and current bootloader. The supported --bootloader options are:

  • touch1200 bootloader is activated by connecting to the board at 1200 baud
  • mpy using micropython to enter the bootloader
  • manual manual intervention is needed to enter the bootloader
  • none mpflash assumes the board is ready to flash

For ESP32 and ESP8266 boards the esptool is used to flash the firmware, and this includes activating the bootloader.

Flashing all connected boards with the latest stable firmware

> mpflash flash
22:15:55 | ℹ️  - Using latest stable version: v1.22.2
                                       Connected boards
┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Serial  Family       Port     Board               CPU          Version         build ┃
┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ COM11   micropython  rp2      RPI_PICO_W          RP2040       1.20.0                │
│ COM12   micropython  esp8266  ESP8266_GENERIC     ESP8266      1.22.2                │
│ COM18   micropython  rp2      RPI_PICO_W          RP2040       1.23.0-preview  155   │
│ COM3    micropython  samd     SEEED_WIO_TERMINAL  SAMD51P19A   1.23.0-preview  155   │
│ COM5    micropython  stm32    PYBV11              STM32F405RG  1.23.0-preview  166   │
│ COM8    micropython  esp32    ESP32_GENERIC_S3    ESP32S3      1.23.0-preview  155   │
└────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘
22:15:58 | ℹ️  - Found v1.22.2 firmware rp2\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM11.
22:15:58 | ℹ️  - Found v1.22.2 firmware esp8266\ESP8266_GENERIC-v1.22.2.bin for ESP8266_GENERIC on COM12.
22:15:58 | ℹ️  - Found v1.22.2 firmware rp2\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM18.
22:15:58 | ℹ️  - Found v1.22.2 firmware samd\SEEED_WIO_TERMINAL-v1.22.2.uf2 for SEEED_WIO_TERMINAL on COM3.
22:15:58 | ⚠️  - Trying to find a firmware for the board PYBV11
22:15:58 |   - No v1.22.2 firmware found for PYBV11 on COM5.
22:15:58 | ⚠️  - Trying to find a firmware for the board ESP32-GENERIC-S3
22:15:58 |   - No v1.22.2 firmware found for ESP32_GENERIC_S3 on COM8.
22:15:58 | ℹ️  - Updating RPI_PICO_W on COM11 to 1.22.2
22:15:58 | ℹ️  - Erasing not yet implemented for UF2 flashing.
22:15:58 | ℹ️  - Entering UF2 bootloader on RPI_PICO_W on COM11
22:15:58 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left
22:15:59 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left
22:16:00 | ℹ️  - Board is in bootloader mode
22:16:00 | ℹ️  - Copying firmware\rp2\RPI_PICO_W-v1.22.2.uf2 to F:
22:16:13 |   - Done copying, resetting the board and wait for it to restart
22:16:23 | ℹ️  - Updating ESP8266_GENERIC on COM12 to 1.22.2
22:16:23 | ℹ️  - Flashing firmware\esp8266\ESP8266_GENERIC-v1.22.2.bin on ESP8266_GENERIC on COM12
22:16:23 | ℹ️  - Running esptool --chip ESP8266 --port COM12 erase_flash 
esptool.py v4.7.0
Serial port COM12
Connecting....
...
Chip erase completed successfully in 6.5s
Hard resetting via RTS pin...
22:16:31 | ℹ️  - Running esptool --chip ESP8266 --port COM12 -b 460800 write_flash --flash_size=detect 0x0 firmware\esp8266\ESP8266_GENERIC-v1.22.2.bin 
esptool.py v4.7.0
Serial port COM12
Connecting....
...
Leaving...
Hard resetting via RTS pin...
22:16:43 | ℹ️  - Done flashing, resetting the board and wait for it to restart
22:16:49 |   - Flashed 1.22.2 to ESP8266_GENERIC on COM12 done
22:16:49 | ℹ️  - Updating RPI_PICO_W on COM18 to 1.22.2
22:16:49 | ℹ️  - Erasing not yet implemented for UF2 flashing.
22:16:49 | ℹ️  - Entering UF2 bootloader on RPI_PICO_W on COM18
22:16:49 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left
22:16:50 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left
22:16:51 | ℹ️  - Board is in bootloader mode
22:16:51 | ℹ️  - Copying firmware\rp2\RPI_PICO_W-v1.22.2.uf2 to F:[/bold]
22:17:02 |   - Done copying, resetting the board and wait for it to restart
22:17:12 | ℹ️  - Updating SEEED_WIO_TERMINAL on COM3 to 1.22.2
22:17:12 | ℹ️  - Erasing not yet implemented for UF2 flashing.
22:17:12 | ℹ️  - Entering UF2 bootloader on SEEED_WIO_TERMINAL on COM3
22:17:12 | ℹ️  - Waiting for mcu to mount as a drive : 10 seconds left
22:17:13 | ℹ️  - Waiting for mcu to mount as a drive : 9 seconds left
22:17:14 | ℹ️  - Board is in bootloader mode
22:17:14 | ℹ️  - Copying firmware\samd\SEEED_WIO_TERMINAL-v1.22.2.uf2 to F:[/bold]
22:17:17 |   - Done copying, resetting the board and wait for it to restart
22:17:27 | ℹ️  - Flashed 4 boards
                               Connected boards after flashing
┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Serial  Family       Port     Board               CPU          Version         build ┃
┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ COM11   micropython  rp2      RPI_PICO_W          RP2040       1.22.2                │
│ COM12   micropython  esp8266  ESP8266_GENERIC     ESP8266      1.22.2                │
│ COM18   micropython  rp2      RPI_PICO_W          RP2040       1.22.2                │
│ COM3    micropython  samd     SEEED_WIO_TERMINAL  SAMD51P19A   1.22.2                │
│ COM5    micropython  stm32    PYBV11              STM32F405RG  1.23.0-preview  166   │
│ COM8    micropython  esp32    ESP32_GENERIC_S3    ESP32S3      1.23.0-preview  155   │
└────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘

Note that if no matching firmware can be found for a board, it will be skipped. (For example, the PYBV11 and ESP32_GENERIC_S3 boards in the example above.)

Contributing and Development

For contributors and developers working on mpflash itself, see the Developer Documentation for:

  • Getting started / local setup
  • Running tests and coverage
  • Building the package
  • Upgrading dependencies
  • Code standards and architecture

Issues and bug reports

Please report any issues or bugs in the issue tracker.

License

mpflash is licensed under the MIT license. See the LICENSE file for more details.

Contributions

Jos Verlinde
Jos Verlinde

💻 🔬 🤔 🖋 💥
shariltumin
shariltumin

💥
Matt Trentini
Matt Trentini

💥
Stewart Russell
Stewart Russell

💥
Andrew Leech
Andrew Leech

💥
Wouter van Ooijen
Wouter van Ooijen

💥
Shane Powell
Shane Powell

💥
Robert Hammelrath
Robert Hammelrath

💥
Bg
Bg

💥
Raul Kompaß
Raul Kompaß

💥
garryp4
garryp4

💥
Shane Powell
Shane Powell

💥
Andy Piper
Andy Piper

💥
David Horton
David Horton

💥

This project follows the all-contributors specification. Contributions of any kind welcome!

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mpflash-1.28.4.tar.gz (3.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mpflash-1.28.4-py3-none-any.whl (206.3 kB view details)

Uploaded Python 3

File details

Details for the file mpflash-1.28.4.tar.gz.

File metadata

  • Download URL: mpflash-1.28.4.tar.gz
  • Upload date:
  • Size: 3.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for mpflash-1.28.4.tar.gz
Algorithm Hash digest
SHA256 7443e57be59e11a1069a69252727296e12553628c30f7e835aecc4edbe783210
MD5 b92b5ca8c4ee60952a0e00d3f47029f7
BLAKE2b-256 adbd80a1c54264b769003834eeb09e5bd76674a8af80ea76ffe3a3e9c67a84b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for mpflash-1.28.4.tar.gz:

Publisher: release.yml on Josverl/mpflash

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mpflash-1.28.4-py3-none-any.whl.

File metadata

  • Download URL: mpflash-1.28.4-py3-none-any.whl
  • Upload date:
  • Size: 206.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for mpflash-1.28.4-py3-none-any.whl
Algorithm Hash digest
SHA256 dbcb6ea0b0d22b16b67d0941840578ffd4a77868e2c3029ba243d9a4d241f6b6
MD5 03bbbda3b3ecebf6c445d1390b512e6d
BLAKE2b-256 a109a20a9c7d1044f6d6d1632ec36f24350757125c37784da6861599745ade44

See more details on using hashes here.

Provenance

The following attestation bundles were made for mpflash-1.28.4-py3-none-any.whl:

Publisher: release.yml on Josverl/mpflash

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page