LittleFS failing to mount on QSPI NOR Flash (err -28)

I am trying to implement LittleFS on 1Gb QSPI NOR flash (W25Q01JV) on the nRF5340.

I am running nRF Connect SDK version 2.4.2 and am using a slightly modified version of the LittleFS example to work with my custom board.

Whenever I try to mount the file system I get this error:

Here is the relevant Device tree bindings:

/ {
    chosen {
        nordic,pm-ext-flash = &w25q01;
    };
    fstab {
		compatible = "zephyr,fstab";
		lfs: lfs {
			compatible = "zephyr,fstab,littlefs";
			mount-point = "/lfs";
			partition = <&lfs_part>;
			read-size = <16>;
			prog-size = <16>;
			cache-size = <64>;
			lookahead-size = <32>;
			block-cycles = <512>;
		};
	};
};

//delete-node/ &storage_partition;

&qspi {
	status = "okay";
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
    w25q01: w25q01@0 {
        compatible = "nordic,qspi-nor";
		reg = <0>;
		writeoc = "pp4o";
		readoc = "read4io";
		sck-frequency = <8000000>;
		jedec-id = [EF 40 21];
        sfdp-bfp = [
        e5 20 fb ff  ff ff ff 3f  44 eb 08 6b  08 3b 42 bb
        fe ff ff ff  ff ff 00 00  ff ff 40 eb  0c 20 0f 52
        10 d8 00 00  36 02 a6 00  82 ea 14 e2  e9 63 76 33
        7a 75 7a 75  f7 a2 d5 5c  19 f7 4d ff  e9 70 f9 a5
        ];
        //has-lock = <0x7C>;
		size = <1073741824>;
		has-dpd;
		t-enter-dpd = <3000>;
		t-exit-dpd = <3000>;
        quad-enable-requirements= "S2B1v1";
        //requires-ulbpr;
        address-size-32;
        enter-4byte-addr= <0xB7>; // 0xA5 is what is reported, but DS says 0xB7?
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;
    
            lfs_part: partition@0 {
                label = "lfs_storage";
                reg = <0x00000000 0x08000000>;
            };
        };
	};
};

And here is my relevant prj.conf settings:

# file system
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_BLK_DEV=y
CONFIG_DISK_ACCESS=y
CONFIG_FILE_SYSTEM_MKFS=y

# nvs and partitioning
CONFIG_NVS=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_NVS=y
CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=65536
CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
CONFIG_PM_PARTITION_SIZE_LITTLEFS=0x8000000
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_FLASH_JESD216_API=y

CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n

I've been messing with Device tree and overlay settings for a while without getting anywhere past this error -28 so far.

I did find that if I removed the CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL setting, it would mount and run, but to the internal flash controller instead of external flash, despite any of the partition settings in the device tree.

I've ran the jesd216 example code to generate the following config information:

w25q01jv@0: SFDP v 1.6 AP ff with 2 PH
PH0: ff00 rev 1.6: 16 DW @ 80
Summary of BFP content:
DTR Clocking supported
Addressing: 3- or 4-Byte
4-KiBy erase: uniform
Support QSPI XIP
Support 1-1-1
Support 1-1-2: instr 3Bh, 0 mode clocks, 8 waits
Support 1-1-4: instr 6Bh, 0 mode clocks, 8 waits
Support 1-2-2: instr BBh, 2 mode clocks, 2 waits
Support 1-4-4: instr EBh, 2 mode clocks, 4 waits
Support 4-4-4: instr EBh, 2 mode clocks, 0 waits
Flash density: 134217728 bytes
ET1: instr 20h for 4096 By; typ 64 ms, max 896 ms
ET2: instr 52h for 32768 By; typ 128 ms, max 1792 ms
ET3: instr D8h for 65536 By; typ 160 ms, max 2240 ms
Chip erase: typ 60928 ms, max 365568 ms
Byte program: type 32 + 3 * B us, max 192 + 18 * B us
Page program: typ 704 us, max 4224 us
Page size: 256 By
Suspend: 75h ; Resume: 7Ah
DPD: Enter B9h, exit ABh ; delay 3000 ns ; poll 0x3d
HOLD or RESET Disable: unsupported
QER: 4
0-4-4 Mode methods: entry 0xd ; exit 0x3d
4-4-4 Mode sequences: enable 0x11 ; disable 0x9
4-byte addressing support: enter 0xa5, exit 0x3e5
Soft Reset and Rescue Sequence support: 0x30
Status Register 1 support: 0x69
size = <1073741824>;
sfdp-bfp = [
        e5 20 fb ff  ff ff ff 3f  44 eb 08 6b  08 3b 42 bb
        fe ff ff ff  ff ff 00 00  ff ff 40 eb  0c 20 0f 52
        10 d8 00 00  36 02 a6 00  82 ea 14 e2  e9 63 76 33
        7a 75 7a 75  f7 a2 d5 5c  19 f7 4d ff  e9 70 f9 a5
        ];
PH1: ff84 rev 1.0: 2 DW @ d0
sfdp-ff84 = [
        ff 0a f0 ff  21 ff dc ff
        ];
jedec-id = [ef 40 21];

I've tried manually declaring the partition in pm_static.yml, as well as modifying a lot of the devicetree and prj.conf settings without any success. I've seen others with similar issues when trying to use a NOR Flash chip greater than 128mb, is it a known issue? Or is there something obviously wrong in my configuration code that I am not catching?

Thanks,

- Brett

  • Hi,

    Could you also test the SPI Flash sample? (It is configured for QSPI for the nRF5340)

    It would be interesting to see if you see the same error without a filesystem.

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd, 
    I ran the example for multiple sectors, and the output looks to be good:




    So If the QSPI flash seems to be working properly, I'd assume the filesystem or partitioning configuration is probably at fault.

    Any ideas for what to change in the configuration?

    - Brett

  • Good to know that that sample works.

    Next up, lets look at partitioning.

    NVS and settings will do partitioning stuff. Can you test littlefs without those and see if that works?

    Do you use the partition manager in your code or not?
    To check this, see if CONFIG_PARTITION_MANAGER_ENABLED is set.
    See this course for an intro to the Partition Manager.

  • With NVM and Settings disabled, I still get the same (err -28). I do use the Partition manager and have confirmed that CONFIG_PARTITION_MANAGER_ENABLED is set.

    I have a pm_static.yml defined as below:

    mcuboot:
      address: 0x0
      end_address: 0x10000
      region: flash_primary
      size: 0x10000
    mcuboot_primary:
      address: 0x10000
      end_address: 0x64000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      size: 0x54000
      span: *id001
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10200
      region: flash_primary
      size: 0x200
    app:
      address: 0x10200
      end_address: 0x64000
      region: flash_primary
      size: 0x53E00
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x64000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x53E00
      span: *id002
    mcuboot_secondary:
      address: 0x64000
      end_address: 0xB8000
      region: flash_primary
      size: 0x54000
    mcuboot_secondary_1:
      address: 0xB8000
      end_address: 0xF8000
      region: flash_primary
      size: 0x40000
    settings_storage:
      address: 0xF8000
      end_address: 0xFC000
      region: flash_primary
      size: 0x4000
    user_storage:
      address: 0xFC000
      end_address: 0x100000
      region: flash_primary
      size: 0x4000
    
    otp:
      address: 0xff8100
      end_address: 0xff83fc
      region: otp
      size: 0x2fc
    
    pcd_sram:
      address: 0x20000000
      end_address: 0x20002000
      region: sram_primary
      size: 0x2000
    sram_primary:
      address: 0x20002000
      end_address: 0x20070000
      region: sram_primary
      size: 0x6e000
    rpmsg_nrf53_sram:
      address: 0x20070000
      end_address: 0x20080000
      placement:
        before:
        - end
      region: sram_primary
      size: 0x10000
    
    mcuboot_primary_1:
      address: 0x0
      size: 0x40000
      device: flash_ctrl
      region: ram_flash
    ram_flash:
      address: 0x40000
      end_address: 0x40000
      region: ram_flash
      size: 0x0
    
    lfs_part:
      address: 0x0
      end_address: 0x8000000
      device: w25q01
      region: external_flash
      size: 0x8000000

    The last entry in pm_static, is where I have tried to statically define the lfs partition on external flash. I have tried with and without this static config, as well as with and without 

    CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y.
    It is worth noting for my use case that I would like to have NVS on internal flash while having LittleFS on external flash. But for the sake of figuring out the issue, we can have NVS disabled for now.
  • As an extra sanity check, I went ahead and ran the littlefs example with nothing changed, except the boards file to have the W25Q01JV instead of the MX25R64. The output was pretty much the same:

    I: littlefs partition at /lfs1
    I: LittleFS version 2.5, disk version 2.0
    I: FS at w25q01@0:0x0 is 2048 0x10000-byte blocks with 512 cycle
    I: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
    E: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1234: Corrupted dir pair at {0x0, 0x1}
    W: can't mount (LFS -84); formatting
    W: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1897: Superblock 0x0 has become unwritable
    E: format failed (LFS -28)
    E: fs mount error (-28)
    E: Automount /lfs1 failed: -28
    *** Booting nRF Connect SDK d96769faceca ***
    Sample program to r/w files on littlefs
    Area 0 at 0x0 on w25q01@0 for 134217728 bytes
    /lfs1 automounted
    E: mount point not found!!
    FAIL: statvfs: -2
    E: fs not mounted (mp == 0x20000054)
    /lfs1 unmount: -22

    The example does not even use the Partition manager, so I dont think it is the cause of these issues.

    One odd thing I am noticing, with the flash size declared in bits using 
    size = <1073741824>; the device tree visualizer shows the whole flash as 1GByte instead of 1Gbit. But the partition size is correct.



    If I try to use 
    size-in-bytes = <134217728>; it shows 0B for flash area on the sample, with the same error output when ran. Meanwhile it wont even compile with size-in-bytes used at all in my main application.




Related