Skip to content

Board profile configuration for RomFS

Andrew Leech edited this page Jun 16, 2025 · 1 revision

ROMFS Board Configuration Guide

This document provides comprehensive guidance for board profile developers on how to add ROMFS (Read-Only Memory File System) support to MicroPython boards.

Overview

ROMFS allows embedding a read-only filesystem directly in flash memory that can be accessed at runtime through the /rom mount point. This feature enables:

  • Fast access to Python modules and data files (faster than FAT/LittleFS)
  • Deployment of applications and libraries without modifying firmware
  • Runtime updates of ROM content via vfs.rom_ioctl() and mpremote

Core Requirements

1. Enable ROMFS Support

Add these defines to your board's mpconfigboard.h:

#define MICROPY_VFS_ROM (1)

This automatically enables MICROPY_VFS_ROM_IOCTL unless explicitly disabled.

Note: When both MICROPY_VFS_ROM and MICROPY_VFS_ROM_IOCTL are enabled, ROMFS will be automatically mounted at /rom during mp_init(). Both /rom and /rom/lib are added to sys.path.

2. Implement Port-Specific rom_ioctl Function

Each port must implement mp_vfs_rom_ioctl() in a vfs_rom_ioctl.c file. This function handles:

  • MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS - Query number of ROM partitions
  • MP_VFS_ROM_IOCTL_GET_SEGMENT - Get partition info (address, size)
  • MP_VFS_ROM_IOCTL_WRITE_PREPARE - Prepare partition for writing (erase)
  • MP_VFS_ROM_IOCTL_WRITE - Write data to partition
  • MP_VFS_ROM_IOCTL_WRITE_COMPLETE - Finalize write operation

Port-Specific Implementation Patterns

STM32 Port

Configuration Options:

// For internal flash storage
#define MICROPY_HW_ROMFS_ENABLE_INTERNAL_FLASH (1)

// For external QSPI flash storage  
#define MICROPY_HW_ROMFS_ENABLE_EXTERNAL_QSPI (1)
#define MICROPY_HW_ROMFS_QSPI_SPIFLASH_OBJ (&spi_bdev_obj)

// Enable partitions (up to 2 supported)
#define MICROPY_HW_ROMFS_ENABLE_PART0 (1)
#define MICROPY_HW_ROMFS_ENABLE_PART1 (1)  // Optional second partition

Linker Script Requirements:

Define partition symbols in your .ld file:

MEMORY
{
    /* Other memory regions... */
    FLASH_ROMFS (rx): ORIGIN = 0x90000000, LENGTH = 1024K
}

/* ROMFS location symbols */
_micropy_hw_romfs_part0_start = ORIGIN(FLASH_ROMFS);
_micropy_hw_romfs_part0_size = LENGTH(FLASH_ROMFS);

/* Optional second partition */
_micropy_hw_romfs_part1_start = ORIGIN(FLASH_ROMFS2);
_micropy_hw_romfs_part1_size = LENGTH(FLASH_ROMFS2);

Example Boards:

  • PYBD_SF2/SF6: Uses external QSPI flash, 1MB partition
  • ARDUINO_GIGA: External QSPI flash support
  • ARDUINO_NICLA_VISION: External QSPI flash support
  • ARDUINO_PORTENTA_H7: External QSPI flash support

RP2 Port

Configuration:

Add to mpconfigboard.h:

#define MICROPY_HW_ROMFS_BYTES (128 * 1024)  // Size in bytes

Memory Layout:

  • ROMFS partition placed at end of firmware allocation
  • Lives between firmware and read/write filesystem
  • Reduces available firmware space by MICROPY_HW_ROMFS_BYTES

Automatic Enablement:

#define MICROPY_VFS_ROM (MICROPY_HW_ROMFS_BYTES > 0)

ESP32 Port

Configuration:

Add to mpconfigboard.h:

#define MICROPY_VFS_ROM (1)

Partition Table:

Create or modify partition CSV file with romfs entry:

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 0x1D0000,
romfs,    data, 0x8f,    0x1E0000, 0x20000,    # 128KB ROM partition
vfs,      data, fat,     0x200000, 0x200000,

Board Configuration:

Specify partition file in board makefile:

PART_SRC = partitions-4MiB-romfs.csv

ESP8266 Port

Configuration:

Add to board variant makefile:

CFLAGS += -DMICROPY_VFS_ROM=1

Linker Script:

Define FLASH_ROMFS memory region and symbols:

MEMORY
{
    /* Other regions... */
    irom0_0_seg :  org = 0x40209000, len = 1M - 36K - 320K  # Reduced firmware space
    FLASH_ROMFS :  org = 0x402b0000, len = 320K             # ROM partition
}

/* ROMFS symbols */
_micropy_hw_romfs_part0_start = ORIGIN(FLASH_ROMFS);
_micropy_hw_romfs_part0_size = LENGTH(FLASH_ROMFS);

Alif Port

Configuration:

Add to mpconfigport.h:

#define MICROPY_VFS_ROM (1)

Hardware Support:

  • OSPI flash memory (external)
  • MRAM (Magnetoresistive RAM) memory
  • Up to 2 partitions supported
  • Similar partition configuration to STM32

Configuration Options:

// Enable partitions
#define MICROPY_HW_ROMFS_ENABLE_PART0 (1)
#define MICROPY_HW_ROMFS_ENABLE_PART1 (1)  // Optional second partition

Linker Script:

Similar to STM32, define partition symbols:

/* ROMFS location symbols */
_micropy_hw_romfs_part0_start = ORIGIN(FLASH_ROMFS);
_micropy_hw_romfs_part0_size = LENGTH(FLASH_ROMFS);

Key Features:

  • Automatic detection of OSPI vs MRAM based on memory addresses
  • Support for both XIP (execute-in-place) and memory-mapped access
  • Hardware-specific address validation for memory safety

Implementation Checklist

Required Files

  1. vfs_rom_ioctl.c - Port-specific ROM I/O control implementation
  2. Board configuration - Add ROMFS defines to mpconfigboard.h
  3. Memory layout - Update linker script or partition table
  4. Build integration - Add vfs_rom_ioctl.c to port Makefile

Key Implementation Points

  1. Partition Management:

    • Support 1-2 partitions per port capabilities
    • Expose partition info via mp_obj_array_t structures
    • Handle partition bounds checking
  2. Flash Operations:

    • Implement erase before write
    • Support incremental writes with offset
    • Handle flash-specific alignment requirements
    • Provide proper error handling
  3. Memory Safety:

    • Validate write boundaries
    • Check partition sizes and alignment
    • Prevent corruption of adjacent areas
  4. Performance Considerations:

    • ROMFS stat operations are significantly faster than FAT/LittleFS
    • Automatically added to sys.path as /rom and /rom/lib
    • Minimal import overhead compared to frozen modules

Testing and Validation

Basic Functionality Test

import vfs

# Query available ROM segments
num_segments = vfs.rom_ioctl(1)
print(f"Available ROM segments: {num_segments}")

# Get segment info
if num_segments > 0:
    segment_info = vfs.rom_ioctl(2, 0)  # Get first segment
    print(f"Segment 0: {segment_info}")

Deployment Test

# Create and deploy ROMFS via mpremote
mpremote romfs build lib/ --output romfs.img
mpremote romfs deploy romfs.img

Runtime Access Test

import os
print("ROM filesystem contents:")
for item in os.listdir('/rom'):
    print(f"  {item}")

Common Pitfalls

  1. Insufficient Flash Space: Ensure adequate flash allocation for ROM partition
  2. Alignment Issues: Respect flash sector/page alignment requirements
  3. Linker Symbol Errors: Properly define partition start/size symbols
  4. Missing Dependencies: Include required flash driver headers
  5. Partition Overlap: Avoid conflicts with firmware or filesystem areas

Best Practices

  1. Size Planning: Reserve 64KB-1MB for typical applications
  2. Partition Layout: Place ROM between firmware and R/W filesystem
  3. Error Handling: Implement comprehensive error checking in rom_ioctl
  4. Documentation: Document partition layout in board documentation
  5. Testing: Validate on actual hardware with various file sizes

Port Status (June 2025)

Port Status Implementation File Notes
STM32 ✅ Complete vfs_rom_ioctl.c Internal + External flash
RP2 ✅ Complete rp2_flash.c External flash only
ESP32 ✅ Complete esp32_partition.c Partition table based
ESP8266 ✅ Complete vfs_rom_ioctl.c External flash only
Alif ✅ Complete vfs_rom_ioctl.c OSPI + MRAM support (NEW)
UNIX ✅ Complete main.c Coverage testing only
QEMU ✅ Complete - VFS_ROM enabled, no ioctl
SAMD ❌ Missing - Port from PR #8381
MIMXRT ❌ Missing - Port from PR #8381
NRF ❌ Missing - Port from PR #8381
RENESAS-RA ❌ Missing - Port from PR #8381
Zephyr ❌ Missing - No implementation
WebAssembly ❌ Missing - No implementation

This guide provides the foundation for implementing ROMFS support on any MicroPython port. Refer to existing implementations for port-specific patterns and adapt as needed for your target hardware.

Clone this wiki locally
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy