Normally, all imported Python modules in CircuitPython are loaded into RAM in compiled form, whether they start as .mpy or .py files. Especially on M0 boards, a user program can run out of RAM if too much code needs to be loaded.

To ameliorate this problem, a CircuitPython image can include compiled Python code that is stored in the image, in flash memory, and executed directly from there. These are "internal frozen modules". The circuitplayground_express  builds use this technique, for example.

If you would like to build a custom image that includes some frozen modules, you can imitate how it's done in the circuitplayground_express build. Look at boards/circuit_playground_express/

USB_VID = 0x239A
USB_PID = 0x8019
USB_PRODUCT = "CircuitPlayground Express"
USB_MANUFACTURER = "Adafruit Industries LLC"

CHIP_FAMILY = samd21


# Turn off displayio to make room for frozen libs.

# Now we actually have a lot of room. Put back some useful modules.

# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor

Notice the FROZEN_MPY_DIRS lines in the file. Pick the file for the board you are using, and add one or more similar lines. You will need to do add directories for the libraries you want to include. If these are existing libraries in GitHub, you can add them as submodules. For instance, suppose you want to add the Adafruit_CircuitPython_HID library to the feather_m0_express build. Add this line to boards/feather_m0_express/

FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID

Then add the library as a submodule:

cd circuitpython/frozen
git submodule add
Set the submodule to a commit that is a release tag. If you try to freeze a module that is at untagged commit, you'll get a git error when building.

When you add the submodule it will be cloned into the frozen/ directory.

Note that there is limited unused space available in the images, especially in the non-Express M0 builds, and you may not be able to fit all the libraries you want to freeze. You can of course try to simplify the library code if necessary to make it fit.

This guide was first published on Apr 26, 2018. It was last updated on Apr 26, 2018.

This page (Adding Frozen Modules) was last updated on Dec 01, 2021.

Text editor powered by tinymce.