MicroPython v1.24

RP2350 lands, RISC-V grows up, ESP32-C6 arrives, and TinyUSB CDC code is unified across five ports.

Released October 26, 2024

🍆
RP2350
ARM and RISC-V on the same chip
ESP32-C6
WiFi 6 + 802.15.4 RISC-V SoC
🔁
RingIO
Thread-safe ring buffer
🌐
ipconfig()
IPv4 + IPv6 network config
0 Contributors
0 Timezones
0 New Boards
RingIO and 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. v1.24 is the release where the webassembly port also gained top-level await of asyncio Tasks.
Two new MCUs

RP2350 & ESP32-C6

v1.24 brings up two important new chips. RP2350 is the headline: Raspberry Pi's successor to the RP2040, with both ARM and RISC-V cores on the same die, in 30- and 48-pin variants. ESP32-C6 is Espressif's RISC-V chip with WiFi 6 and 802.15.4 (Thread / Zigbee).

Interactive Demo — RP2350: ARM or RISC-V?
RP2350 Raspberry Pi's 2024 MCU Cortex-M33 core 0 Cortex-M33 core 1 ARM
Native emitter
@micropython.native → Thumb v1
Inline assembler
@micropython.asm_thumb
Board
RPI_PICO2 (default ARM build)

The RP2350 ships with both an ARM Cortex-M33 and a RISC-V Hazard3 core pair on the same die. The bootrom selects which cores to wake at startup, controlled by the firmware build. v1.24 lands MicroPython support for both modes.

ESP32-C6

RISC-V + WiFi 6
RV32 + WiFi 6
802.15.4 radio
native emitter

Espressif's RISC-V SoC with WiFi 6 and 802.15.4 (Thread / Zigbee). v1.24 enables the RV32IMC native emitter on both C3 and C6, so @micropython.native-decorated functions compile to tight RISC-V machine code on these chips.

ESP32_GENERIC_C6 M5STACK_NANOC6 UM_TINYC6

RP2350 details

pico-sdk v2.0.0
  • 30- and 48-pin variants — both supported.
  • IPv6 enabled by default on the rp2 port.
  • USB stays active during machine.lightsleep().
  • Optional network.PPP — lwIP-based, opt-in.
  • RP2040 still fully supported — same firmware family, just a new board.
RPI_PICO2
New

RISC-V 32-bit Native Emitter

MicroPython has had native code generation for ARM, Thumb, Xtensa and x86/x64 for years. v1.24 adds RV32IMC: @micropython.native now compiles directly to RISC-V machine code, no interpretation. Decorated functions land in .mpy files (and can be frozen) just like other architectures. v1.24 also adds RISC-V NLR and GC register-scanning, plus semihosting for testing under qemu.

RV32 native emitter port support

esp32 (C3)
esp32 (C6)
rp2 (RP2350 / RV)
qemu (rv32)
unix (rv32)
main.py — works identically across architectures
import micropython

@micropython.native
def crc16(data, init=0xffff):
    crc = init
    for b in data:
        crc ^= b
        for _ in range(8):
            crc = (crc >> 1) ^ 0xa001 if crc & 1 else crc >> 1
    return crc & 0xffff

# On RP2350 (RV mode) and ESP32-C3/C6, this compiles to RV32IMC.
# On RP2040 / RP2350 (ARM mode), it compiles to Thumb.
# On Xtensa esp32 / S2 / S3, Xtensa LX6 / LX7.
qemu becomes a first-class test target
The qemu-arm port has been renamed to just qemu and now supports both ARM and RISC-V. It runs tests via a pty serial port — emulating bare-metal targets — which makes architecture-portable testing much more practical.
New

micropython.RingIO — Thread-Safe Ring Buffer

A new built-in class providing an efficient, byte-oriented ring buffer with a stream interface. Thread-safe, fixed allocation, no GC pressure at runtime — ideal for producer/consumer patterns between an ISR and the main loop, between cores, or between the REPL and a background task. Try it below in your browser.

Live demo PyScript

RingIO is a stream — you can read(), write(), and readinto() just like a file. The buffer is fixed-size and FIFO; reads block (in a real port) when empty.

Loading MicroPython…

In a real-world MicroPython program, RingIO shines in scenarios where one side runs in an interrupt handler (a hard IRQ, even). The fixed allocation means no heap pressure, and the implementation is reentrant on every supported port.

New API

network.ipconfig() — IPv6-aware Network Config

v1.24 introduces network.ipconfig() at module level and nic.ipconfig() on individual interfaces. The new API supports IPv4 and IPv6 with much more control than the legacy nic.ifconfig(). The old API still works (backwards compatibility), but new code should prefer ipconfig().

Legacy ifconfig() — IPv4 only
import network

nic = network.WLAN(network.STA_IF)
nic.active(True)
nic.connect("ssid", "pw")

# Tuple shape: (ip, mask, gw, dns)
nic.ifconfig((
    "192.168.1.50",
    "255.255.255.0",
    "192.168.1.1",
    "8.8.8.8",
))
print(nic.ifconfig())
ipconfig()v1.24+, IPv4 + IPv6
import network

nic = network.WLAN(network.STA_IF)
nic.active(True)
nic.connect("ssid", "pw")

# Keyword args; pick what you need
nic.ipconfig(
    addr4=("192.168.1.50", "255.255.255.0"),
    gw4="192.168.1.1",
    dhcp4=False,
)
network.ipconfig(dns="2606:4700:4700::1111")  # IPv6 DNS

print(nic.ipconfig("addr4"))
print(nic.ipconfig("addr6"))
Plus: portable PPP
A new network.PPP class based on lwIP is also available in v1.24. Not enabled by default, but boards that already use bare-metal lwIP can opt in — the rp2 port already exposes it as an option, and stm32 follows.
Cross-port

TinyUSB CDC unification & portable UART IRQ API

Five ports that previously each had their own TinyUSB integration now share common helper code for CDC serial. As a side effect, the REPL banner and initial prompt are buffered until host connection — so the first thing you see when you connect is the banner, not silence.

Most ports also gain a portable UART IRQ API. Register Python callbacks for IRQ_RX, IRQ_RXIDLE, IRQ_TXIDLE and IRQ_BREAK with consistent semantics across the family.

Unified TinyUSB CDC

esp32 (S2 / S3)
mimxrt
renesas-ra
rp2
samd

Portable UART.irq()

esp32
mimxrt
nrf
renesas-ra
rp2
samd
stm32 (had it already)
main.py — works the same on every supported port
from machine import UART

uart = UART(0, baudrate=115200)

def on_rx(u):
    print("got", u.read())

uart.irq(handler=on_rx, trigger=UART.IRQ_RX | UART.IRQ_RXIDLE)
New

Python language tweaks

Three core-language changes in v1.24, including a breaking change to sys.exit(). Pick one from the dropdown to load the example, then run it live.

Live demo PyScript
Loading MicroPython…

Webassembly: top-level await of Task and Event
The webassembly port (which is what makes this page possible) gained an important asyncio improvement in v1.24: you can now await a Task or Event at module top level. This means a <script type="mpy"> block can do result = await some_task() directly, with no asyncio.run() wrapping. PyScript also gained JsProxy identity reuse, attribute lookup without existence checks, and JS iterable proxying.

Highlights

Other notable improvements in v1.24.

🎯

esp32 firmware shrank by 53 kB

The IDF v5.0.5 -> v5.2.2 update plus internal cleanup gives back over 50 kB of flash on every esp32 build (-3.10%). Big win for memory-constrained boards.

esp32
👨🏻‍💻

mpremote hash-based recursive copy

New mpremote sha256sum command, plus recursive copy that first hashes and only updates files that differ. Large-app sync becomes fast.

mpremote
🔗

SoftSPI LSB mode

machine.SoftSPI now supports least-significant-bit-first ordering, in addition to MSB.

machine

sys.exit() — breaking change

Now triggers a soft reset of the device instead of just dropping to the REPL. Brings bare-metal in line with the unix port. May impact applications that relied on the old behaviour.

core
🔬

STM32H7 OctoSPI

OctoSPI memory-mapped flash support on STM32H7 MCUs. New ARDUINO_OPTA stm32 board.

stm32
🏠

stm32: code in RAM for UART REPL

Build option places IRQ + flash + UART code in RAM, enabled on boards with a UART REPL so filesystem operations don't drop characters during flashing (e.g. when copying files via mpremote).

stm32
👤

Arduino + NXP SE05x secure element

ARDUINO_PORTENTA_H7 and ARDUINO_NICLA_VISION gain SE05x integration via mbedTLS — hardware-backed crypto.

stm32
🔬

zephyr v3.7 + threading

Zephyr port updated to v3.7.0; threading via _thread is now implemented. REPL is non-blocking. _thread tests now pass. Big-int support enabled.

zephyr
🔭

zephyr device-tree object construction

Construct machine objects (Pin, I2C, SPI…) directly from device-tree node labels, no more hard-coded peripheral indices.

zephyr
🍉

qemu: ARM + RISC-V, with REPL

The qemu port runs both architectures via a pty-based REPL, mirroring how real bare-metal tests work. Tests that previously needed a board can now run in CI.

qemu
🔘

esp32: TCP socket cap

Hard limit on active TCP sockets prevents resource exhaustion when applications open sockets in quick succession.

esp32
🌐

webassembly FFI improvements

JsProxy gains iterable-protocol proxying, identity reuse, no-existence-test attribute lookup, and configurable pystack size. Top-level await of Task / Event (covered in the language section above).

webassembly

New Boards

10 new board definitions, weighted heavily toward ESP32-C6 and RP2350-class boards.

By the Numbers

v1.24 in numbers. esp32 firmware actually shrank by 53 kB after the ESP-IDF cleanup — the only port-shrink across the five recent releases.

0
Contributors
0
Timezones
0
New Boards

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

unix x64
+1.10% — GCM and ECDHE-RSA mbedTLS config
+8994 B
rp2
+1.07% — RP2350 + RingIO + UART.irq
+3592 B
esp8266
+0.43% — ipconfig + RingIO
+2968 B
samd
+0.85% — RingIO + UART.irq
+2244 B
mimxrt
+0.51% — RingIO + UART.irq
+1864 B
renesas-ra
+0.25% — RingIO + UART.irq
+1536 B
nrf
+0.78% — RingIO + UART.irq
+1460 B
cc3200
+0.62% — ipconfig + WLAN.ipconfig
+1152 B
stm32
+0.26% — new RingIO class
+1028 B
minimal x86
+0.10% — int.to_bytes() buffer-size fixes
+185 B
bare-arm
+0.20% — int.to_bytes() buffer-size fixes
+116 B
esp32
-3.10% — ESP-IDF cleanup (v5.0.5 -> v5.2.2)
-53617 B
Adrian Higgins, Alessandro Gatti, Alexandre Iooss, Amirreza Hamzavi, Andrea Milazzo, Andrew Leech, Angus Gratton, Ayush Singh, cajt, Christian Walther, Corran Webster, Damien George, Dan Halbert, danicampora, David Lechner, dmfaria, Dryw Wade, Elvis Pfützenreuter, Felix Dörre, George Hopkins, Glenn Moloney, iabdalkader, IhorNehrutsa, Jared Hancock, Jason Kridner, Jim Mussared, Jon Foster, Jos Verlinde, Junwha, Laurens Valk, Lennart, Leo Chung, Matt Trentini, Matthias Blankertz, Maureen Helm, Michael Sawyer, Michael Vornovitsky, nspsck, Owen, Paul Grayson, Peter Harper, Peter Züger, Phil Howard, Plaque FCC, Rick Sorensen, robert-hh, Seon Rozenblum, shiggy, stijn, Sylvain Zimmer, Takeo Takahashi, Terence Stenvold, tharuka, Tim Weber, timdechant, Volodymyr Shymanskyy, Yoctopuce, ZodiusInfuser.