MicroPython v1.25

ROMFS ships after three years in development, plus a brand-new alif port and an inline RISC-V assembler.

Released April 16, 2025

💾
ROMFS
Execute mpy in place from flash
🧠
alif port
Ethos-U55 ML accelerators
asm_rv32
Inline RISC-V 32-bit machine code
🔒
DTLS
Datagram TLS over UDP sockets
0 Contributors
0 Timezones
0 New Boards
The language demos on this page run real MicroPython in your browser. MicroPython is compiled to WebAssembly via PyScript and executes live as the page loads — no server required.
New — 3 years in development

ROMFS — Execute Bytecode in Place

ROMFS is a read-only, memory-mappable filesystem that lets MicroPython execute precompiled .mpy bytecode directly from flash, without copying it into RAM first. The result: faster imports and a lot less heap pressure. Data resources like fonts can also be used in place. ROMFS builds on bytecode v6 (which has supported in-place execution for years).

Interactive Demo — Import a Module
Without ROMFS — bytecode copies to RAM
FLASH (.mpy bytecode) RAM 0 kB used
With ROMFS — bytecode runs in place
FLASH /rom (mmapped) RAM 0 kB used

The demo simulates a small import. In real MicroPython, bytecode v6 + ROMFS lets the VM execute opcodes directly from a memory-mapped flash region; only the per-call frame needs to live in RAM. Imports of large modules become noticeably faster.

Building & deploying ROMFS — mpremote

terminal
# 1. Build a ROMFS image from a directory tree of .py / .mpy / data files
$ mpremote romfs build romfs.bin --src ./assets
Built ROMFS image: 32 kB

# 2. Deploy it to the /rom partition on the target device
$ mpremote romfs deploy romfs.bin
Deployed to /rom

# 3. Imports now resolve transparently from /rom
$ mpremote run app.py

Where ROMFS is enabled by default in v1.25

Other boards can opt in with manual configuration. The list will grow in subsequent releases.

PYBD-SFx (stm32)
alif (all boards)
ESP8266 FLASH_2M_ROMFS variant
stm32 Arduino boards
Brand new port

alif — Multi-core ARM with ML Accelerators

A new port targeting Alif Semiconductor's Ensemble family. These MCUs pair multiple ARM cores with Ethos-U55 machine-learning accelerators and a generous peripheral set. v1.25 brings up the platform with TinyUSB, OpenAMP-based dual-core support, octal-SPI flash with XIP, and the machine classes plus cyw43 WiFi+BLE.

Alif Ensemble

Multi-core ARM
M55 + M0+
U55 NPU
XIP octal flash

Targeted at battery-powered ML inference at the edge. v1.25 supports Pin, UART, SPI, I2C, USB via TinyUSB, and dual-core orchestration via OpenAMP. cyw43 WiFi and BLE work on boards that include the radio module.

ALIF_ENSEMBLE OPENMV_AE3

What's running where

Dual-core via OpenAMP
  • Cortex-M55 (HE) — high-performance core where MicroPython executes by default.
  • Cortex-M0+ (LP) — low-power core; OpenAMP makes it addressable from MicroPython.
  • Ethos-U55 NPU — per-core neural-network accelerator; not yet exposed at the Python layer in v1.25.
  • OPENMV_AE3 targets OpenMV's upcoming AE3 camera board — the ML angle is the headline use case.
New decorator

@micropython.asm_rv32 — Inline RISC-V 32-bit assembly

MicroPython's inline-assembler family gains RV32. Write small snippets of 32-bit RISC-V machine code as Python functions. Currently enabled on the rp2 port when the RP2350 is in RISC-V mode.

Pure Python (Viper)
@micropython.viper
def add_squared(a: int, b: int) -> int:
    return a*a + b*b
Inline RV32 assembly
@micropython.asm_rv32
def add_squared(a0, a1) -> int:
    # a0 *= a0      ; a0 = a*a
    mul(a0, a0, a0)
    # a1 *= a1      ; a1 = b*b
    mul(a1, a1, a1)
    # a0 += a1      ; return a*a + b*b
    add(a0, a0, a1)
Where it works
The asm_rv32 decorator is enabled on rp2 when targeting RP2350 in RISC-V mode (Hazard3 cores). The same release also extends the native emitter and mpy_ld.py linker to support 32-bit RISC-V code generation and static-library linking, so native modules can be built for RV32 targets.
New

DTLS — Datagram TLS

The tls module gains PROTOCOL_DTLS_CLIENT and PROTOCOL_DTLS_SERVER modes. Wrap a UDP socket in a DTLS context and you have an authenticated, encrypted datagram channel — useful for CoAP-secure, low-latency telemetry, and constrained-network protocols where TCP is the wrong tool.

TLS over TCP — familiar
import tls, socket

ctx = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT)
ctx.load_verify_locations(cadata=ca)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("example.com", 443))
ss = ctx.wrap_socket(s, server_hostname="example.com")
ss.send(b"GET / HTTP/1.0\r\n\r\n")
DTLS over UDP — new in v1.25
import tls, socket

ctx = tls.SSLContext(tls.PROTOCOL_DTLS_CLIENT)
ctx.load_verify_locations(cadata=ca)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("sensor.example", 5684))
ss = ctx.wrap_socket(s, server_hostname="sensor.example")
ss.send(b"telemetry payload")

DTLS Port Support

alif
mimxrt
renesas-ra
rp2
stm32
unix
New

Python language tweaks

Five small core-language additions in v1.25. Pick one from the dropdown to load the example into the editor, then run it live.

Live demo PyScript
Loading MicroPython…

marshal: enabled, but not in this build
v1.25 also added a marshal module with dumps() / loads() for code objects — combined with function.__code__ that gives you function serialisation. The MicroPython release tag explicitly notes: "This module is not enabled by default but can be used in custom build configurations." The PyScript variant of MicroPython runs at the FULL_FEATURES ROM level, which doesn't include marshal — so we can't demo it here. Try it on a desktop unix build with MICROPY_PY_MARSHAL=1.

Highlights

Other notable improvements in v1.25.

🗑

mpremote rm -r

Recursive remove on the target device. mpremote rm -rv : wipes the current working directory.

mpremote
📦

mip install from local FS

Install a package from a local directory or relative URL via package.json. Useful for offline / air-gapped setups.

mpremote
🔗

Default I2C / SPI / UART buses

On samd, mimxrt, rp2 and others, the bus-id argument is now optional — cross-port code can drop the explicit id.

machine
🔌

esp32 dynamic USB devices

USB device configuration at runtime on ESP32-S2 / S3, plus IDF v5.3 / v5.4 support (sub-5.2.0 dropped). I2S enabled on all C3 boards.

esp32
🏘

RP2350 PSRAM autodetection

RP2350 boards with PSRAM auto-size on boot. rp2.bootsel_button() and USB-during-sleep both work on RP2350.

rp2
🔐

WPA3 on cyw43 boards

Pico W, Pico 2 W and stm32 cyw43-driver boards now support WPA3 in both AP and STA modes.

rp2stm32

stm32 deinit on soft-reset — breaking

I2C and SPI buses are now deinitialised on soft-reset. Always re-initialise instances when creating them.

stm32
📋

littlefs corruption recovery

stm32 boots no longer hard-fault on corrupt filesystems. Falls back to default block parameters, then prints a message and continues.

stm32

zephyr Timer + WDT

The zephyr port gains machine.Timer and machine.WDT implementations, narrowing the cross-port API gap.

zephyr
📥

mimxrt UF2 + exFAT + PPP

UF2 bootloader support for easier firmware deployment, exFAT filesystem, and PPP driver for boards with lwIP networking.

mimxrt
🔌

RV32 native modules

mpy_ld.py now supports 32-bit RISC-V code, plus automatic linking of static libraries (libgcc, libm) so native modules can use standard C functions like exp().

native modules
🛡

mboot version string

stm32 mboot embeds a version at the end of its flash slot; fwupdate.get_mboot_version() retrieves it.

stm32

New Boards

19 new board definitions, dominated by RP2350-class rp2 boards and the brand-new alif port.

By the Numbers

v1.25 in numbers. unix and mimxrt take big code-size hits from VfsRom + exFAT; rp2 grows for DTLS + cyw43-driver 1.1.0.

0
Contributors
0
Timezones
0
New Boards

Code size delta vs v1.24 (.text section, bytes)

unix x64
+2.05% — enable VfsRom, mbedTLS v3.6.2, DTLS
+16941 B
esp32
+0.65% — many small fixes and improvements
+10956 B
rp2
+0.87% — mbedTLS v3.6.2, DTLS, cyw43-driver 1.1.0
+7944 B
mimxrt
+2.07% — enable exFAT, function constructor
+7508 B
samd
+0.42% — UART 9-bit, function constructor, default buses
+1112 B
esp8266
+0.14% — function attrs, Pin.toggle(), AP enumeration
+964 B
cc3200
+0.15% — Pin.toggle()
+280 B
nrf
+0.09% — sys.implementation._build, 2-arg next(), vfs.mount()
+168 B
bare-arm
+0.01% — tracking only
+4 B
minimal x86
-0.05% — small code-size optimisations
-90 B
stm32
-0.03% — small code-size optimisations
-96 B
renesas-ra
-0.03% — small code-size optimisations
-160 B
Alessandro Gatti, Alex Brudner, Amirreza Hamzavi, Andrew Leech, Angus Gratton, Anson Mansfield, Carl Pottle, Christian Clauss, chuangjinglu, Corran Webster, Damien George, danicampora, Daniël van de Giessen, Dryw Wade, eggfly, Garry W, garywill, Glenn Moloney, Glenn Strauss, Graeme Winter, Hans Maerki, Herwin Grobben, I. Tomita, iabdalkader, IhorNehrutsa, Jan Klusáček, Jan Sturm, Jared Hancock, Jeff Epler, Jon Nordby, Jos Verlinde, Karl Palsson, Keenan Johnson, Kwabena W. Agyeman, Lesords, machdyne, Malcolm McKellips, Mark Seminatore, Markus Gyger, Matt Trentini, Mike Bell, Neil Ludban, Peter Harper, peterhinch, Phil Howard, robert-hh, Ronald Weber, rufusclark, Sebastian Romero, Steve Holden, stijn, StrayCat, Thomas Watson, Victor Rajewski, Volodymyr Shymanskyy, Yoctopuce.