Greetings,
I have previously added the LittleFS to the internal flash of the nRF52840 with success using the available documentation. Our .dts & and code is shown below.
/{ fstab { compatible = "zephyr,fstab"; lfs1: lfs1 { compatible = "zephyr,fstab,littlefs"; mount-point = "/lfs1"; partition = <&storage_partition>; automount; read-size = <16>; prog-size = <16>; cache-size = <64>; lookahead-size = <32>; block-cycles = <512>; }; }; }; /* Flash configuration copied from nRF52840DK */ &flash0 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 0x0000C000>; }; slot0_partition: partition@c000 { label = "image-0"; reg = <0x0000C000 0x00067000>; }; slot1_partition: partition@73000 { label = "image-1"; reg = <0x00073000 0x00067000>; }; scratch_partition: partition@da000 { label = "image-scratch"; reg = <0x000da000 0x0001e000>; }; /* * The flash starting at 0x000f8000 and ending at * 0x000fffff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ storage_partition: partition@f8000 { label = "storage"; reg = <0x000f8000 0x00008000>; }; }; };
#define PARTITION_NODE DT_NODELABEL(lfs1) FS_FSTAB_DECLARE_ENTRY(PARTITION_NODE); static struct fs_mount_t *mp = &FS_FSTAB_ENTRY(PARTITION_NODE);
prj.conf
# Flash File System configuration CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_LITTLEFS=y
After this configuration, we were able to use the internal flash to store/retrieve data with ease.
Now we want to mount a second instance of LittleFS to an external flash memory (SPI NOR W25Q512NW). We have tried two different ways but both result in the same.
1st implementation:
.DTS file
/ { chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,pm-ext-flash = &w25q512nw; }; &spi1{ compatible = "nordic,nrf-spi"; status = "okay"; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; cs-gpios = < &gpio0 26 GPIO_ACTIVE_LOW >; w25q512nw: w25q512nw@0 { compatible = "jedec,spi-nor"; status = "okay"; label = "W25Q512NW"; wp-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; hold-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; reg = < 0 >; spi-max-frequency = < 8000000 >; jedec-id = [ ef 60 20 ]; // Manufacturer ID = EFh, Memory Type (ID15-ID8) = 60h and Capacity (ID7-ID0) = 20h size = < 536870912 >; // Flash capacity in bits = 512M-bit = 1024 * 1024 * 512 * 1bit = 536870912 bit has-dpd; t-enter-dpd = < 3000 >; // in nanoseconds - The power-down state will entered within the time duration of tDP: 3us t-exit-dpd = < 30000 >; // in nanoseconds - The Release from power-down will take the time duration of tRES1: 30us }; };
Code:
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(_LfsConfig); static struct fs_mount_t lfs_storage_mnt = { .type = FS_LITTLEFS, .fs_data = &_LfsConfig, // .storage_dev = (void *)DT_FLASH_AREA_STORAGE_ID, .storage_dev = (void *)FLASH_AREA_ID(littlefs_storage), .mnt_point = "/lfs2" };
prj.conf
# SPI NOR configuration CONFIG_SPI=y CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 # Partition Manager Setttings CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n
2nd implementation:
.dts file:
/ { chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,pm-ext-flash = &w25q512nw; }; }; &spi1{ compatible = "nordic,nrf-spi"; status = "okay"; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; cs-gpios = < &gpio0 26 GPIO_ACTIVE_LOW >; w25q512nw: w25q512nw@0 { compatible = "jedec,spi-nor"; status = "okay"; label = "W25Q512NW"; wp-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; hold-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; reg = < 0 >; spi-max-frequency = < 8000000 >; jedec-id = [ ef 60 20 ]; // Manufacturer ID = EFh, Memory Type (ID15-ID8) = 60h and Capacity (ID7-ID0) = 20h size = < 536870912 >; // Flash capacity in bits = 512M-bit = 1024 * 1024 * 512 * 1bit = 536870912 bit has-dpd; t-enter-dpd = < 3000 >; // in nanoseconds - The power-down state will entered within the time duration of tDP: 3us t-exit-dpd = < 30000 >; // in nanoseconds - The Release from power-down will take the time duration of tRES1: 30us partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; /* 64 MB partition to use for LFS filesystem */ ext_storage_partition: partition@0000000 { label = "littlefs_storage"; reg = <0x0000000 0x2000000>; }; }; }; };
Code:
#define FLASH_EXT_PARTITION_NODE DT_NODELABEL(lfs2) FS_FSTAB_DECLARE_ENTRY(FLASH_EXT_PARTITION_NODE); static struct fs_mount_t *lfs_storage_mnt = &FS_FSTAB_ENTRY(FLASH_EXT_PARTITION_NODE);
prj.conf
# SPI NOR configuration CONFIG_SPI=y CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 # Partition Manager Setttings CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n
For both these implementation, we get the same result, it seems that the two LittleFS file systems are mounted to the same place which is the internal SoC flash memory because the logs we get is shown below:
[00:00:00.002,502] <inf> littlefs: littlefs partition at /lfs1 [00:00:00.002,532] <inf> littlefs: LittleFS version 2.4, disk version 2.0 [00:00:00.002,777] <inf> littlefs: FS at flash-controller@4001e000:0xf8000 is 6 0x1000-byte blocks with 512 cycle [00:00:00.002,777] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32 [00:00:00.002,868] <err> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1077: Corrupted dir pair at {0x0, 0x1} [00:00:00.002,899] <wrn> littlefs: can't mount (LFS -84); formatting [00:00:00.175,292] <inf> littlefs: /lfs1 mounted [00:00:00.175,292] <inf> littlefs: Automount /lfs1 succeeded [00:00:00.175,323] <inf> littlefs: littlefs partition at /lfs2 [00:00:00.175,323] <inf> littlefs: LittleFS version 2.4, disk version 2.0 [00:00:00.175,567] <inf> littlefs: FS at flash-controller@4001e000:0xf8000 is 6 0x1000-byte blocks with 512 cycle [00:00:00.175,598] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32 [00:00:00.175,842] <inf> littlefs: /lfs2 mounted [00:00:00.175,872] <inf> littlefs: Automount /lfs2 succeeded
As seen in Line 3 & Line 11 the File Systems seem to be mounted at the same partition in the internal SoC flash.
How could we make the second instance of LittleFS to be mounted correctly in the external flash (while still keeping the first instance mounted on the internal SoC flash)?
Thank you and I look forward to hearing from you!
Best Regards,
Stavros