ESP32C5, ESP32P4 & STM32U5 support, enhanced test suite, port Tier levels
This release of MicroPython adds support for ESP32-C5 and ESP32-P4 microcontrollers. The ESP32-P4 can work either standalone as a general purpose processor, or with an external wireless co-processor, currently either an ESP32-C5 or ESP32-C6. Board profiles are provided for all three of these configurations, as well as for the new ESP32-C5.
Support for the low-power and high performing STM32U5xx series is also added in this release, supporting USB, ADC, DAC, UART, I2C, SPI and RTC, with a board profile for the NUCLEO-U5A5ZJ-Q.
Rigorous and ongoing hardware-based testing is an important part of MicroPython, and with the increasing number of supported hardware platforms -- along with a growing test suite -- it's important to make the tests run as smoothly and as automated as possible. This release makes progress here by making many improvements to the test suite, such as:
auto-detecting if the target has unicode support
automatically including float tests when possible
always including stress tests
improving the skipping of tests that use slice and the micropython module
supporting different expected outputs when running native tests
making tests behave in low-memory condition
tweaking some tests so they can run on minimal builds
making all test runners use the -t argument to select the target
converting some tests to use unittest
converting some port-specific tests to cross-port tests
adding a test for serial (REPL) reliability and throughput
updating to use CPython 3.8.2 as the reference Python version
adding more internal benchmark tests.
In order to support testing on more hardware targets in a scalable way, this release introduces board-specific target_wiring.py configuration. This feature allows defining in one location (one file) all the needed test-related hardware connections for a given port or board, definitions which are then imported and used by the tests that need them. Along with providing default definitions, this scheme allows custom hardware to easily specify its own wiring set up for the tests. To start with, all of the machine.UART tests have been converted to use target_wiring.py.
With all the improvements to the test suite, the MicroPython continuous integration (CI) tests now run on the unix minimal variant, and as many tests as possible now run on the zephyr port CI.
MicroPython now defines port Tier levels, which categorizes the 20 existing ports into four groups according to their stage of development. This aims to set expectations for the level of support and development each port receives. And also lower the bar of entry for new ports so they can enter at a low Tier and gradually rise up to Tier 1. See the top-level README.md and the docs at https://docs.micropython.org/en/latest/develop/support_tiers.html
This release also sees MicroPython drop support for Python 2.7 in its build scripts and tools. Python 2.7 has been EOL since January 2020 and all modern operating systems support Python 3.
There have been quite a few other improvements, optimizations and bug fixes to the core runtime, including: better 32-bit RISC-V code generation for the native emitter and Zba opcode support, support for relative imports in custom __import__ callback, bool and len unary operation support for dict views, support for start and end position in re match and search methods and IPv6 support in asyncio.start_server(). Most ports (except esp32) now support soft and hard IRQ callbacks for machine.Timer objects. And the sys module is now enabled at all feature levels by default.
Some third party libraries have been updated in this release: LittleFS is now at v2.11.2, TinyUSB is at 0.19.0-24, and stm32lib has N6 at 1.2.0, WB at 1.23.0 and newly added U5 support. The mimxrt's nxp_driver submodule has been restructured to match the official mcux-sdk.
The alif port sees the addition of machine.RTC.datetime() to get and set the RTC, as well as time.time_ns(). Also a fix for USB device address setting on fast USB hosts, and fixing of machine.SPI.init() to only change requested settings.
The esp32 port has been updated to use ESP-IDF v5.5.1, and, as mentioned, now supports ESP32-C5 and ESP32-P4. TinyUSB integration has been improved, with a bug fix for Zero Length Packets that affected REPL reliability, along with a fix for blank USB HID reports on boards with PSRAM. network.PPP has had some important fixes to its thread safety, and the espnow module can now set the rate without giving an error. I2S has been enabled on all ESP32-C6 boards and a new esp32.wake_on_gpio() function has been added to support waking up the SoC via GPIO pins.
The qemu port now supports 64-bit RISC-V and adds the VIRT_RV64 board definition, and also adds MPS2_AN500 (Cortex-M7) and MPS3_AN547 (Cortex-M55) boards. These all aid in testing MicroPython on different architectures.
For the rp2 port DMA channels are now properly stopped when they are freed, PIO now supports pin wrapping and fixes the use of RP2350B upper-bank pins, and pin alternate functions have been fixed for pins greater than 31. UART_AUX, XIP_CS1, CORESIGHT_TRACE and HSTX alternate functions have been added for RP2350 MCUs.
The stm32 port adds support for STM32U5xx series MCUs, as well as STM32F469xx. STM32G0xx sees the addition of DAC support, and fixes to ADC, Timer(4) and RTC wakeup. STM32G4xx now has a hardware I2C implementation, and STM32L4xx supports I2CTarget. LAN now works on STM32N6xx MCUs, including support for gigabit Ethernet with the RTL8211 PHY. There is also now optional support for using TinyUSB as the USB stack, to replace the existing STM USB stack. Although the latter is still the default USB stack the intention is to eventually in a future release switch over to use TinyUSB, which allows defining USB devices in Python.
The unix and windows ports have had their main REPL loop replaced with the standard REPL loop code that is used by all the bare-metal ports. This makes it more consistent, and in particular it now supports raw REPL.
The zephyr port upgraded Zephyr to v4.2.0, now has the machine.ADC class, a new VFS interface to the native Zephyr filesystem, support for a GC split heap, added set/get sensor attributes to zsensor, and supports hard IRQ timer callbacks. It will now format the default flash partition if necessary on boot, following other bare-metal ports. New boards include PocketBeagle 2, XIAO BLE NRF52840 SENSE, and NXP MIMXRT1020 EVK.
New boards added in this release are: ESP32_GENERIC_C2 FLASH_2M variant, ESP32_GENERIC_C5, ESP32_GENERIC_P4 with standard, C5_WIFI and C6_WIFI variants, SIL_MANT1S and SOLDERED_NULA_MINI (esp32 port), NUCLEO_H7A3ZI_Q, NUCLEO_U5A5ZJ_Q, STM32F469DISC and WEACTSTUDIO_MINI_STM32H743 (stm32 port).
The change in code size since the previous release for select builds of various ports is (absolute and percentage change in the text section):
unix: use standard bare-metal REPL, update micropython-lib submodule (includes argparse improvements).
stm32: support soft IRQ timer callbacks (a refactoring), add MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC.
cc3200: correctly format leading zeros with separators, add support for start and end position in re, and other minor improvements to the core.
esp8266: support hard IRQ timer callbacks, correctly format leading zeros with separators.
esp32: use IDF 5.5.1 (+30k), update RMT to use the new IDF API.
mimxrt: update TinyUSB, add support for start and end position in re.
renesas-ra: correctly format leading zeros with separators, add support for start and end position in re.
nrf: print SPI baudrate, polarity and phase, improved timeout handling for UART, correctly format leading zeros with separators.
rp2: enable hashlib.md5, update TinyUSB.
samd: update TinyUSB, correctly format leading zeros with separators.
Thanks to everyone who contributed to this release: Alessandro Gatti, Alex Tran, Andrew Leech, Angus Gratton, Anson Mansfield, Ayush Singh, Chris Liechti, Chris Mason, Chris Webb, Christian Clauss, Craftzman7, Damien George, Daniël van de Giessen, David Lechner, David Schneider, Dryw Wade, Elvis Pfutzenreuter, ennyKey, Florent, garywill, iabdalkader, Ihor Nehrutsa, Jared Hancock, Jeff Epler, Jimisola Laursen, John Smith, Jos Verlinde, Josip Šimun Kuči, Kwabena W. Agyeman, Matt Trentini, Maureen Helm, Meir Armon, Mike Tolkachev, Mike Wang, Ned Konz, Patrick Van Oosterwijck, Peter Harper, Phil Howard, robert-hh, Steve Sanbeg, stijn, Thomas Watson, Tico06, Vdragon, Vincent1-python, Yanfeng Liu, Yilin Sun, yuan_mo, Yuuki NAGAO.
MicroPython is a global Open Source project, and contributions were made from the following timezones: -0800, -0700, -0600, -0500, -0400, -0300, +0000, +0100, +0200, +0300, +0530, +0800, +0900, +1000, +1100.
The work done in this release was funded in part through GitHub Sponsors, and in part by George Robotics, Espressif, Arduino, OpenMV, and Planet Innovation.
What follows is a detailed list of changes, generated from the git commit history, and organised into sections.
Main components
all:
remove Python 2.7 support
use "static inline" consistently in function definitions
replace legacy name with MicroPython and MPy as applicable
simplify mp_int_t/mp_uint_t definition
define and describe the port Tier levels
update ruff configuration to target Python 3.8
py core:
asmrv32: make lt/le comparisons emitter shorter
binary: add MICROPY_PY_STRUCT_UNSAFE_TYPECODES
misc: add explicit dependency on py/mpconfig.h
objringio: detect incorrect constructor calls
mkrules.cmake: clean genhdr and frozen_mpy dirs
parse: remove explicit checks for invalid folding operations
objtype: make mp_obj_new_type a static function
misc: add a way to detect sanitizer builds
asmthumb: fix T3 encoding of conditional branches
objtype: use locals_ptr directly instead of getting it from the slot
mpconfig: rename MICROPY_PY___FILE__ to MICROPY_MODULE___FILE__
mpconfig: move MICROPY_MODULE___ALL__ option to other module options
mpconfig: enable CRYPTOLIB, HASHLIB_MD5, HASHLIB_SHA1 if SSL enabled
builtinimport: guard code needing sys.path with MICROPY_PY_SYS_PATH
mpconfig: enable the sys module at all feature levels by default
obj: fix a comment regarding make_new slot
obj: remove unused map new/free function declarations
parsenum: fix parsing LLONG_MIN in longlong configuration
mkrules.mk: force ".pp" files to always rebuild
makeversionhdr.py: always abbreviate Git hashes to same length
obj: update with_finaliser version to match mp_obj_malloc_var
gc: clean up usage of GC_ALLOC_FLAG_HAS_FINALISER flag
compile: throw SyntaxError instead of asserting
stream: add a stream.readinto1() method for machine.UART
stream: support additional arguments for mp_stream_write1_obj
remove unneeded future imports
obj: document undocumented MP_TYPE_FLAG values
py.cmake: add nlraarch64
mpstate: make it possible for mpy-cross to set emitter options
asmrv32: use RV32 Zba opcodes if possible
emitinlinerv32: add Zba opcodes to the inline assembler
stream: reuse write implementation for readinto
objrange: allow return of non-small ints
mkrules.mk: add %.sz rule to print size of an object file
objint: fix converting float to int with OBJ_REPR_B
runtime: support importing a method from an instance
add MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC
modmath: make MICROPY_PY_MATH_POW_FIX_NAN also fix pow(x, NaN) cases
mpconfig: introduce SIZE_FMT macro
runtime: fix printing of failed allocation amounts
scheduler: allow selective handling in mp_handle_pending
misc: use _Static_assert for MP_STATIC_ASSERT where possible
misc: don't warn about a GNU extension for static assert macro
py.mk: regenerate moduledefs.h if makemoduledefs.py changes