Is it possible for micropython running on STM32 to expand memory through PSRAM?
Is it possible for micropython running on STM32 to expand memory through PSRAM?
Thanks for your help.
mimxrt: Add initial PSRAM implementation.
Summary
PSRAM support for Teensy 4.1 and other mimxrt boards! Resolves #18281
This implementation is a copy of the Arduino core PSRAM implementation here. I modified the implementation to use the #defines from lib/nxp_driver/sdk/devices/MIMXRT1062/MIMXRT1062.h where possible instead of the huge imxrt.h. However there's still about a dozen that I had to copy over from imxrt.h that currently live in psram.c; happy to change/move these if there's a better solution!
The MicroPython side of things is a copy of the rp2 PSRAM PR (#15620). I have not looked into whether MICROPY_ALLOC_GC_STACK_SIZE needs to be increased nor if any clock timings need to change, like was done in the rp2 PR. There may be other edge cases that need to be addressed, but I'm new to Teensy/mimxrt, so don't know what to look for :slightly_smiling_face:
Testing
<!-- Explain what testing you did, and on which boards/ports. If there are
boards or ports that you couldn't test, please mention this here as well.
If you leave this empty then your Pull Request may be closed. -->
The following test code prints the total amount of memory seen by the garbage collector, then performs a memory test with a small and large bytearray to demonstrate the split heap working.
import gc
import uctypes
gc.collect()
print("Initial GC free (MiB):", gc.mem_free() / 1024 / 1024)
def test(size):
gc.collect()
b = bytearray(size)
print("Test size:", size, "location: 0x{:X}".format(uctypes.addressof(b)), end=' ')
for i in range(size):
b[i] = i & 0xFF
for i in range(size):
if b[i] != (i & 0xFF):
print("Fail at", i)
return
print("Pass!")
test(10)
test(10_000_000)
Testing with a single 16MiB chip, the GC shows over 16MiB available. The small array is allocated in the 0x20000000 range (DTCM), and the large array is allocated in the 0x70000000 range (PSRAM). All behaves as I'd expect!
Initial GC free (MiB): 16.358551025390626
Test size: 10 location: 0x20204720 Pass!
Test size: 10000000 location: 0x7005DD00 Pass!
Note that test(10_000_000) takes ~25 seconds on my end.
Trade-offs and Alternatives
<!-- If the Pull Request has some negative impact (i.e. increased code size)
then please explain why you think the trade-off improvement is worth it.
If you can think of alternative ways to do this, please explain that here too.
Delete this heading if not relevant (i.e. small fixes) -->
There could be an argument for PSRAM support being enabled by default, at least for Teensy 4.1 (set #define MICROPY_HW_ENABLE_PSRAM (1) in boards/TEENSY41/mpconfigboard.h). This implementation auto-detects the presence and size of 1 or 2 PSRAM chips if they're soldered, meaning a user wouldn't need to flash different firmware.
Building on my end, enabling PSRAM increases the firmware size from 626992 to 628064 bytes (+1072 / +0.17%), so I'll defer to others whether it's worth enabling it by default. If not, might be nice to create a variant with PSRAM enabled so it's easy to get from the Teensy 4.1 download page.