← index #6605PR #5330
Related · medium · value 1.086
QUERY · ISSUE

STM32L432KC "can't" create flash filesystem

openby ZSorcereropened 2020-11-08updated 2024-09-08
port-stm32

I have designed a custom pyboard used STM32L432KC as the controller and downloaded both V1.12 and V1.13 NUCLEO_L432KC as the firmare. Neither of them works,the file system can not be loaded. I can not mount the flash.

I already set the following parameters:

#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1)  //   in file mpconfigboard.h
#define MICROPY_HW_ENABLE_USB       (1)   //   in file mpconfigboard.h
#define MICROPY_HW_USB_MSC          (1)    //   in file mpconfigboard.h
#define MICROPY_HW_USB_HID          (1)    //   in file mpconfigboard.h

And

MEMORY    //   in file stm32l432.ld
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 246K /* sectors 0-114 */    
    FLASH_FS (rx)    : ORIGIN = 0x0803D800, LENGTH = 10K /* sectors 115-127 */          I want 10k file system, therefore  ORIGIN = 0x0803D800
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 64K /* SRAM1, 48K + SRAM2, 16K */
}

And

MICROPY_VFS_FAT = 1         //   in file mpconfigboard.mk

I have successfully compiled the code and downloaded it into my L432 board. After I reset the board, I got the following output:

mpy

The REPL works fine.
But, there are 2 ERRORS:
(1)Can't create flash system.
(2)Can't mount flash.

I know the flash size for STM32L432KC is only 256kb which is tiny, but 5kb~10kb file system is enough for me. I only need to implement some basic GPIO operations.

I also used the printf function to check where the program went wrong.

in main.c , the following function gives nonzero value of ret which is -5.

int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point)

because the expression

 (nlr_push(&nlr)  ≠ 0

Here is the complete function:

#if MICROPY_HW_ENABLE_STORAGE
STATIC int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) {
    nlr_buf_t nlr;
    mp_int_t ret = -MP_EIO;
    nlr_push_test();
    if (nlr_push(&nlr) == 0) {
        mp_obj_t args[] = { bdev, mount_point };
        mp_vfs_mount(2, args, (mp_map_t*)&mp_const_empty_map);
        mp_vfs_chdir(mount_point);
        ret = 0; // success
        nlr_pop();
    } else {
        mp_obj_base_t *exc = nlr.ret_val;
        if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exc->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
            mp_obj_t v = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(exc));
            mp_obj_get_int_maybe(v, &ret); // get errno value
            ret = -ret;
        }
    }
    return ret;
}

Why this expression (nlr_push(&nlr) ≠ 0 , how to slove this problem? I think this caused the failure of the flash FS.

Another error came from factoryreset.c . in the following function:

MP_WEAK int factory_reset_create_filesystem(void) {
    // LED on to indicate creation of local filesystem
    led_state(PYB_LED_GREEN, 1);
    uint32_t start_tick = HAL_GetTick();

    fs_user_mount_t vfs;
    pyb_flash_init_vfs(&vfs);
    uint8_t working_buf[FF_MAX_SS];
    FRESULT res = f_mkfs(&vfs.fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
    if (res != FR_OK) {
        mp_printf(&mp_plat_print, "MPY: can't create flash filesystem\n");    // **This is the ERROR message**
        return -MP_ENODEV;
    }

    // Set label
    f_setlabel(&vfs.fatfs, MICROPY_HW_FLASH_FS_LABEL);

    // Populate the filesystem with factory files
    factory_reset_make_files(&vfs.fatfs);

    // Keep LED on for at least 200ms
    systick_wait_at_least(start_tick, 200);
    led_state(PYB_LED_GREEN, 0);

    return 0; // success
}

#endif // MICROPY_HW_ENABLE_STORAGE

it means the condition (res != FR_OK) is not satisfied.

Can anyone tell me how to revise the code to creat the file system for this L432 board, thanks.

@dpgeorge @boochow @chrismas9 @davehylands

CANDIDATE · PULL REQUEST

stm32: littlefs support

mergedby dpgeorgeopened 2019-11-14updated 2019-11-27
port-stm32

This PR aims to add littlefs support to the stm32 port. It builds upon #5299 (generalise flash mounting code in stm32); see #3847, #5167 and #5249 for prior attempts at stm32+littlefs.

The commits here do a few things:

  • Extend the pyb.Flash() class so it can represent sections/partitions of the flash. Eg pyb.Flash(start=0, len=1024*1024) creates a 1MiB block device at the start of the flash.
  • Extend the pyb.Flash() class to support the extended block protocol.
  • Add support to stm32's main so it can automatically detect the first filesystem on the flash (even if the FS doesn't use all the flash) and mount it appropriately.

With this PR one can use littlefs on PYBv1.x (using just internal flash, 512 byte blocks), and on PYBD (using external SPI flash, 4k byte blocks). Other boards can also be supported, with internal or external flash, but they don't have the new features enabled.

On PYBv1.x and PYBD to switch the entire storage to a littlefs filesystem do:

>>> import pyb, os
>>> fl = pyb.Flash(start=0) # create object accessing entire flash
>>> os.VfsLfs2.mkfs(fl)

On PYBD to create two partitions/filesystems, the first being a FAT the second being a littlefs, do:

>>> import pyb, os
>>> fl1 = pyb.Flash(start=0, len=1024*1024) # 1MiB partition
>>> fl2 = pyb.Flash(start=1024*1024) # remaining 1MiB
>>> os.VfsFat.mkfs(fl1) # format FAT on partition 1
>>> os.VfsLfs2.mkfs(fl2) # format littlefs2 on partition2

The first filesystem will be mounted automatically on boot at /flash (retains old behaviour), whether it's a FAT or LFS. You can then mount any other filesystems manually, eg for PYBD example just above:

os.mount(pyb.Flash(start=1024*1024), '/lfs')

There is a little bit of "magic" behind the scenes to select either 512 or 4096 byte block sizes when using FAT vs LFS. All it is is that littlefs passes a flag along to the block device when initialising it, to indicate that it will use the extended block device. The flash block device then configures itself for 4k block sizes. (The point is that for stm32 the flash storage originally had 512 byte blocks, and now it needs to support both 512 byte and 4096 byte blocks to accommodate both FAT and LFS efficiently.)

IMO this is the "simplest" set of changes that makes littlefs "just work" on stm32, with the goals that 1) the user can dynamically select FAT or LFS by simply formatting as desired; 2) 512 byte blocks are still used for FAT, and 4096 byte blocks are used for LFS.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied