After enabling MCUBoot in NCS, external flash doesn't get picked up by littleFS

Hello:

I am using an nrf52840 on a custom board with W25Q01NV NOR Flash with the Nordic QSPI-NOR driver. Programming is with NCS v 1.8.0 (upgraded yesterday) and the VS Code extension.  I am using the external Flash partition only for storage of data collected by the device and not for use with MCUBoot or for anything else. This setup was previously working with nrf5 SDK and recently moved to NCS.

When the CONFIG_BOOTLOADER_MCUBOOT option is not enabled, the code works fine, mounts the parittion and starts recording the data, but when I enable MCUBoot, LittleFS mounts on an internal flash parition. I found this related issue here: https://devzone.nordicsemi.com/f/nordic-q-a/62212/external-spi-flash-to-use-with-littlefs-on-nrf9160-w-mcuboot, but that was from a year ago and there was no resolution to that issue.

Again, I do not want to store MCUBoot images on the external flash, but I want to still use it for storage and I need MCUBoot enabled for upgrades as usual with the internal flash only. 

Any help is appreciated. 

Ashwin

Parents
  • Could you run the command below from the build folder and upload the result here?

    ninja partition_manager_report

    Best regards,

    Simon 

  • Thanks Simon. This is the output of the patition manager report. 


    flash_primary (0x100000 - 1024kB):
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB) |
    +---0xc000: mcuboot_primary (0x77000 - 476kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B) |
    +---0xc200: mcuboot_primary_app (0x76e00 - 475kB)-+
    | 0xc200: app (0x76e00 - 475kB) |
    +-------------------------------------------------+
    | 0x83000: mcuboot_secondary (0x77000 - 476kB) |
    | 0xfa000: littlefs_storage (0x6000 - 24kB) |
    +-------------------------------------------------+

    sram_primary (0x40000 - 256kB):
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+
  • These are my DTS definitions of the parittions:

    &flash0 {

    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    boot_partition: partition@0 {
    label = "mcuboot";
    reg = <0x000000000 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 0x0008000>;
    };
    };
    };
    And the overlay definition for the external flash is:
    /delete-node/ &storage_partition;

    / {
    fstab {
    compatible = "zephyr,fstab";
    lfs1: lfs1 {
    compatible = "zephyr,fstab,littlefs";
    mount-point = "/lfs1";
    partition = <&lfs1_part>;
    //automount;
    read-size = <32>;
    prog-size = <32>;
    cache-size = <64>;
    lookahead-size = <32>;
    block-cycles = <512>;
    };
    };
    };

    &w25q01jv {
    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    lfs1_part: partition@0 {
    label = "storage";
    reg = <0 0x8000000 >;
    };
    };
    };
    Am I missing something in the definitions? The above DTS works fine without MCUBoot.
Reply
  • These are my DTS definitions of the parittions:

    &flash0 {

    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    boot_partition: partition@0 {
    label = "mcuboot";
    reg = <0x000000000 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 0x0008000>;
    };
    };
    };
    And the overlay definition for the external flash is:
    /delete-node/ &storage_partition;

    / {
    fstab {
    compatible = "zephyr,fstab";
    lfs1: lfs1 {
    compatible = "zephyr,fstab,littlefs";
    mount-point = "/lfs1";
    partition = <&lfs1_part>;
    //automount;
    read-size = <32>;
    prog-size = <32>;
    cache-size = <64>;
    lookahead-size = <32>;
    block-cycles = <512>;
    };
    };
    };

    &w25q01jv {
    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    lfs1_part: partition@0 {
    label = "storage";
    reg = <0 0x8000000 >;
    };
    };
    };
    Am I missing something in the definitions? The above DTS works fine without MCUBoot.
Children
  • Try setting CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n in the prj.conf of your application. Then the secondary slot will no longer be located in the external flash

    If you have enabled external flash and mcuboot, the secondary slot will automatically be placed in the ext. flash. The config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY will get the value 'y'.


    An important thing to be aware of is that the flash partitions from the DTS will be ignored if the sample have child images. The partitions from the Partition Manager will be used instead. For example when you enable MCUboot, your application will add MCUboot as a child image (see <application>/build/mcuboot) and the DTS flash partitions will get ignored.

    The partitions from the Partition Mangager will be generated dynamically bases on pm.yml files, for example:

    or they can be set statically, like it's done in the matter/lock sample:

    https://github.com/nrfconnect/sdk-nrf/blob/v1.8.0/samples/matter/lock/configuration/nrf52840dk_nrf52840/pm_static.yml

    Read more about the Partition Manager in the documentation:

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.8.0/nrf/scripts/partition_manager/partition_manager.html

  • Thank you Simon, for your detailed reply. Let me try all of these points and get back with the result. 

  • I have now added these to the pm_static.yml

    external_flash:
    address: 0x120000
    placement:
    after:
    - mcuboot_secondary
    size: 0x6e0000
    device: W25Q01JV
    region: external_flash
    littlefs_storage:
    address: 0x00000
    size: 0x7a000
    device: W25Q01JV
    region: external_flash
    And now the littlefs_storage doesn't seem to be located in primary flash:

      flash_primary (0x100000 - 1024kB): 

    +-------------------------------------------------+

    | 0x0: mcuboot (0xc000 - 48kB)                    |

    +---0xc000: mcuboot_primary (0x7a000 - 488kB)-----+

    | 0xc000: mcuboot_pad (0x200 - 512B)              |

    +---0xc200: mcuboot_primary_app (0x79e00 - 487kB)-+

    | 0xc200: app (0x79e00 - 487kB)                   |

    +-------------------------------------------------+

    | 0x86000: mcuboot_secondary (0x7a000 - 488kB)    |

    +-------------------------------------------------+

      sram_primary (0x40000 - 256kB): 

    +--------------------------------------------+

    | 0x20000000: sram_primary (0x40000 - 256kB) |

    +--------------------------------------------+

    But when the code starts, it still seems to pickup from the same NRV_FLASH_DRV_NAME paritition. 
    *** Booting Zephyr OS build v2.7.0-ncs1 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot [00:00:00.143,432] [0m<inf> littlefs: littlefs partition at /lfs1[0m
    *** Booting Zephyr OS build v2.7.0-ncs1 ***
    [00:00:00.143,676] [0m<inf> sdc_hci_driver: SoftDevice Controller build revision:
    df c0 4e d6 1f 7c 66 09 0a f5 2b a0 98 f2 43 64 |..N..|f. ..+...Cd
    62 c5 a6 2a |b..* [0m
    Bluetooth initialized
    Advertising successfully started
    Found device MAX17262
    Found device LSM6DSL
    Found device TPS65721
    Found device MAX30003
    Starting in PatchPro ModeSend Data Thrd STRT

    Mounting Disk...

    Area 0 at 0x0 on NRF_FLASH_DRV_NAME for 49152 bytes
    [00:00:00.649,719] [0m<inf> littlefs: LittleFS version 2.2, disk version 2.0[0m
    [00:00:00.649,780] [0m<inf> littlefs: FS at NRF_FLASH_DRV_NAME:0x0 is 12 0x1000-byte blocks with 512 cycle[0m
    [00:00:00.649,780] [0m<inf> littlefs: sizes: rd 32 ; pr 32 ; ca 64 ; la 32[0m
    [00:00:00.649,871] [1;31m<err> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:997: Corrupted dir pair at {0x0, 0x1}[0m
    [00:00:00.649,871] [1;33m<wrn> littlefs: can't mount (LFS -84); formatting[0m
    [00:00:00.680,755] [1;31m<err> os: ***** BUS FAULT *****[0m
    It looks to me like that this is picked up from some other place.
  • I don't have W25Q01NV NOR Flash. But I was able to get this to work using the nRF52840 DK an it's integrated external flash.

    In the sample below, the littlefs storage is placed inside the external flash, and the secondary slot is placed in the primary slot

    2654.littlefs_ext_flash_sec_slot_in_internal.zip

    If it works successfully, you should get the following output:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    Area 1 at 0x0 on MX25R64 for 24576 bytes
    /lfs mount: 0
    [/lfs: bsize = 16 ; frsize = 4096 ; blocks = 6 ; bfree = 4
    00/lfs/boot_count stat: 0
            fn 'boot_count' size 4
    :00/lfs/boot_count read count 2: 4
    /lfs/boot_count seek start: 0
    /lfs/boot_count write new boot count 3: 4
    :00/lfs/boot_count close: 0
    .00/lfs opendir: 0
      F 4 boot_count
    End of files
    /lfs unmount: 0
    7,843] <inf> littlefs: LittleFS version 2.2, disk version 2.0
    [00:00:00.007,873] <inf> littlefs: FS at MX25R64:0x0 is 6 0x1000-byte blocks with 512 cycle
    [00:00:00.007,873] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
    [00:00:00.009,826] <inf> littlefs: /lfs mounted
    [00:00:00.043,334] <inf> littlefs: /lfs unmounted

    This is the result after running ninja partition_manager_report:

      external_flash (0x800000 - 8192kB): 
    +-----------------------------------------+
    | 0x0: external_flash (0x800000 - 8192kB) |
    | 0x0: littlefs_storage (0x6000 - 24kB)   |
    +-----------------------------------------+
    
      flash_primary (0x100000 - 1024kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x7a000 - 488kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x79e00 - 487kB)-+
    | 0xc200: app (0x79e00 - 487kB)                   |
    +-------------------------------------------------+
    | 0x86000: mcuboot_secondary (0x7a000 - 488kB)    |
    +-------------------------------------------------+
    
      sram_primary (0x40000 - 256kB): 
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+

    Could you test this first with the nRF52840 DK, and if that runs successfully, modify it it to work with the W25Q01JV.

    Best regards,

    Simon 

Related