Skip to content

Add LittleFS support for internal flash storage#263

Open
ThomasFarstrike wants to merge 10 commits intoducalex:devfrom
ThomasFarstrike:dev-littlefs
Open

Add LittleFS support for internal flash storage#263
ThomasFarstrike wants to merge 10 commits intoducalex:devfrom
ThomasFarstrike:dev-littlefs

Conversation

@ThomasFarstrike
Copy link

Overview

This PR adds optional LittleFS support to retro-go's internal flash storage subsystem, allowing retro-go to use LittleFS as an alternative to FAT for managing internal flash partitions.

Motivation

During development of the fri3d-2024 target, we encountered unexplained sporadic incompatibility issues between retro-go and MicroPython when both were sharing the same internal storage partition. These issues appeared to stem from differences in filesystem implementations—potentially due to different FAT versions, wear-leveling layer configurations, or other compatibility settings.

Since MicroPython defaults to LittleFS for internal storage (the modern standard for embedded systems), the most pragmatic solution is to add LittleFS support to retro-go. This way, we achieve good interoperability when both systems need to access the same internal storage.

Why LittleFS?

LittleFS is an excellent fit for microcontroller applications:

  • Wear-leveling: Distributes writes evenly across flash memory, extending device lifespan
  • Power-loss resilience: Designed to handle unexpected power failures without corruption
  • Smaller footprint: Minimal RAM and code size requirements, ideal for embedded systems
  • Modern standard: Increasingly adopted across embedded platforms (MicroPython, Zephyr, etc.)
  • Compatibility: Aligns retro-go with the ecosystem's direction

Changes

  • Added optional RG_STORAGE_FLASH_PARTITION_LITTLEFS configuration flag
  • When enabled, internal flash partitions are mounted as LittleFS instead of FAT
  • Maintains backward compatibility—FAT remains the default when the flag is not set
  • Updated storage initialization and cleanup routines to handle both filesystems

Testing

This implementation has been tested with:

  • retro-core: Verified core emulation functionality with LittleFS storage
  • prboom-go: Confirmed game loading and save state management work correctly
  • fri3d-2024 target: Validated interoperability with MicroPython on shared storage

Backward Compatibility

The changes are fully backward compatible. Existing configurations continue to use FAT by default. LittleFS support is opt-in via the RG_STORAGE_FLASH_PARTITION_LITTLEFS configuration flag.

It seems access() doesn't work on littlefs,
while stat() works on both littlefs and fat.

This was initially noticed in prboom-go, because it does an access()
to check if the WAD exists and this one gave an "IWAD not found".
@ThomasFarstrike
Copy link
Author

I included esp_littlefs as a git submodule to avoid copy-paste. But I'm not sure whether you'd prefer a git submodule or a source copy instead. I'm starting to suspect the latter, otherwise you have to clone with "git clone --recurse-submodules".

Let me know if you want me to change it :-)

@ThomasFarstrike
Copy link
Author

Or rg_tool.py doing the clone?

@ThomasFarstrike
Copy link
Author

I tested this with esp-idf 5.4 , which worked fine except for a few deprecation warnings.
Do you think it's time to update BUILDING.md to make it official?

Because access() isn't compatible with littlefs.
@ducalex
Copy link
Owner

ducalex commented Dec 25, 2025

I think I would prefer to vendor in esp_littlefs (source copy) instead of using a submodule! I'm reluctant to add external remote dependencies to retro-go for multiple reasons, and that one is small and self-contained so it should be fine to copy it.

- Use fast access() method by default for better performance
- Fall back to stat() only when RG_STORAGE_FLASH_PARTITION_LITTLEFS is defined

This maintains LittleFS compatibility while preserving performance on FAT.
@ThomasFarstrike
Copy link
Author

Sure, that makes sense. Done!

I also added a little README.md in the components folder to explain what is there; especially the exact versions of the source copies.

@ducalex
Copy link
Owner

ducalex commented Jan 7, 2026

A bit of a tangent but do you know why esp_littlefs doesn't implement access_p?

I imagine that littlefs has no concept of permissions but it could always return success on R_OK|W_OK|X_OK and only concern itself with F_OK? Am I missing something? That would be more elegant than having to patch applications, which I really want to avoid when possible.

@ducalex ducalex force-pushed the dev branch 8 times, most recently from 3df5df1 to 6ff291c Compare January 10, 2026 18:59
@ThomasFarstrike
Copy link
Author

A bit of a tangent but do you know why esp_littlefs doesn't implement access_p?

Hmmm, no I don't know why that is...

@ducalex ducalex force-pushed the dev branch 4 times, most recently from ea87924 to 745c140 Compare January 19, 2026 18:11
@ducalex ducalex force-pushed the dev branch 2 times, most recently from 7a55bb6 to fa7ea78 Compare January 19, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants