Hi Javier,

Littles needs more than 2 blocks. At least 4 are required IIRC, but more to
be really functional. When working with flash always remember that a
complete page needs to be erased before it can be reused, when there are
only 2 blocks everything needs to fit in one block (nothing can be stored
in ram because a reboot could destroy it).

Hope this helps,

Kind regards,

Jehudi

On Wed, Oct 22, 2025, 18:12 Javier Alonso <[email protected]>
wrote:

> Hello devs,
>
> I'm playing around with some LittleFS configuration on an STM32G0 device. I
> have the following snippet:
>
> ```
> #ifdef CONFIG_MTD_PROGMEM
> struct mtd_dev_s * mtd;
> /* Initialize on-chip program memory support */
> mtd = stm32_progmem_initialize();
> if (mtd == NULL)
>   {
>     syslog(LOG_ERR, "ERROR: stm32_progmem_initialize() failed\n");
>   }
> else
>   {
>     ret = ftl_initialize(0, mtd);
>     if (ret < 0)
>      {
>        syslog(LOG_ERR, "ERROR: ftl_initialize() failed: %d\n", ret);
>      }
>    }
> #endif /* CONFIG_MTD_PROGMEM */
> #ifdef CONFIG_FS_LITTLEFS
> ret = nx_mount("/dev/mtdblock0", "/mnt/progmem", "littlefs", 0,
> "autoformat");
> if (ret < 0)
>   {
>     syslog(LOG_ERR, "ERROR: Failed to mount littlefs at /mnt/progmem:
> %d\n", ret);
>   }
> #endif
> ```
> (I'm omitting the internals, but I've implemented the "progmem" layer for
> the STM32G0 with the required "up_" functions).
>
> So far the code runs correctly until the "nx_mount" call is reached. It
> fails with "ret = -28", which stands for "ENOSPC". I've been digging around
> some forums and it seems the LFS configuration may be wrong. For instance:
>
> ```
> fs->cfg.context = fs;
> fs->cfg.read = littlefs_read_block;
> fs->cfg.prog = littlefs_write_block;
> fs->cfg.erase = littlefs_erase_block;
> fs->cfg.sync = littlefs_sync_block;
> fs->cfg.read_size = fs->geo.blocksize *
>                     CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR;
> fs->cfg.prog_size = fs->geo.blocksize *
>                     CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR;
> fs->cfg.block_size = fs->geo.erasesize *
>                      CONFIG_FS_LITTLEFS_BLOCK_SIZE_FACTOR;
> fs->cfg.block_count = fs->geo.neraseblocks /
>                       CONFIG_FS_LITTLEFS_BLOCK_SIZE_FACTOR;
> fs->cfg.block_cycles = CONFIG_FS_LITTLEFS_BLOCK_CYCLE;
> fs->cfg.cache_size = fs->geo.blocksize *
>                      CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR;
> ```
>
> The geometry is directly obtained from the underlying FTL MTD device. For
> this particular case, I'm reserving 4KB at the end of the flash to be used
> as user memory with a fixed page size of 2KB and 2 pages.
>
> - up_progmem_neraseblocks -> 2
> - up_progmem_isuniform -> true
> - up_progmem_pagesize(n) -> 2048
> - up_progmem_erasesize(n) -> 2048
>
> I've tried changing the different LFS configurations, so now I have:
>
> - CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1
> - CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1
> - CONFIG_FS_LITTLEFS_BLOCK_SIZE_FACTOR=1
> - CONFIG_FS_LITTLEFS_BLOCK_CYCLE=200 (default)
> - CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1
> - CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=0
> - CONFIG_FS_LITTLEFS_ATTR_MAX=1022 (default)
>
> Is there anything I need to tweak or adjust for LFS to work? So far I've
> been unable to make it, it fails on the mount stage.
>
> Thanks in advance,
>
> Javier Alonso (he, him, his)
> Geotab
>
> Team Lead - Embedded Systems | GEUR
>

Reply via email to