Mass Example with External Flash not working with CONFIG_BOOTLOADER_MCUBOOT=y

Hi,

I have got the sample "samples/subsys/usb/mass" working on a nrf52840dk using the external flash, but as soon as I enable the mcuboot bootloader (CONFIG_BOOTLOADER_MCUBOOT=y) it does not work anymore. Has anyone got a MSD example working with the mcuboot bootloader enabled using the external flash as the storage device?

I use the NRF CONNECT SDK version v.2.3.0. Any help would be appreciated.

Kind Regards

Julian

  • Hi Hieu,

    That is correct it does not work out of the box for me, or should I say out of the "sandbox" :P.

    No problems. Thanks for the heads-up. We can look at this when you are back (but I would like to resolve this as I am already at 96% of my application space in my code with size optimization on, so I will definitely need it in the not too distant future).

    As promised how to run FATFS with external NOR flash with MCUBOOT.

    prj.conf:

    CONFIG_STDOUT_CONSOLE=y
    
    # CONFIG_LOG=y
    # CONFIG_RTT_CONSOLE=y
    # CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=y
    
    CONFIG_FLASH=y
    
    # Enable mcumgr.
    CONFIG_MCUMGR=y
    
    # Enable most core commands.
    CONFIG_MCUMGR_CMD_IMG_MGMT=y
    CONFIG_MCUMGR_CMD_OS_MGMT=y
    
    # Ensure an MCUboot-compatible binary is generated.
    CONFIG_BOOTLOADER_MCUBOOT=y
    
    CONFIG_MULTITHREADING=y
    
    # Some command handlers require a large stack.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    
    CONFIG_MCUMGR_SMP_UART=y
    
    CONFIG_MCUBOOT_IMAGE_VERSION="0.1.1+8"
    
    CONFIG_PM_PARTITION_REGION_SETTINGS_STORAGE_EXTERNAL=y
    
    
    #USB related configs
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Very FATFS storage"
    CONFIG_USB_DEVICE_PID=0x0008
    CONFIG_LOG=y
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_USB_CDC_ACM=n
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_APP_WIPE_STORAGE=y
    

    create a file called pm_static.yml in the same location as the normal prj.conf and put this in there:

    app:
      address: 0xc200
      end_address: 0x86000
      region: flash_primary
      size: 0x79e00
    external_flash:
      address: 0
      end_address: 0x780000
      region: external_flash
      size: 0x780000
    mcuboot:
      address: 0x0
      end_address: 0xc000
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xc000
    mcuboot_pad:
      address: 0xc000
      end_address: 0xc200
      placement:
        align:
          start: 0x1000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0xc000
      end_address: 0x86000
      orig_span: &id001
      - app
      - mcuboot_pad
      region: flash_primary
      sharers: 0x1
      size: 0x7a000
      span: *id001
    mcuboot_primary_app:
      address: 0xc200
      end_address: 0x86000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x79e00
      span: *id002
    mcuboot_secondary:
      address: 0x86000
      end_address: 0x100000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
        align_next: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x7a000
    settings_storage:
      address: 0x780000
      device: MX25R64
      end_address: 0x800000
      region: external_flash
      size: 0x80000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    

    (I created a 512kB drive right at the end of the external flash, you can increase the size in the file above and in the overlay file below to reflect your desired size):

    create the dts overlay file like below:

    / {
    	chosen {
    		nordic,pm-ext-flash = &mx25r64;
    	};
    };
    
    /delete-node/ &storage_partition;
    
    &mx25r64 {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
            settings_storage: partition@780000 {
                 label = "storage";
                 reg = <0x000780000 0x00080000>;
                             
            };
    	};
    };
    
    / {
        msc_disk0 {
            compatible = "zephyr,flash-disk";
            partition = <&settings_storage>;
            disk-name = "NAND";
            cache-size = <4096>;
        };
    };

    Create the folders called child_image/mcuboot and pop a prj.conf file in it and paste the following in there (the child_image folder should be in the same location as CMakeLists and the pm_static file, etc):

    # MCUboot requires a large stack size, otherwise an MPU fault will occur
    CONFIG_MAIN_STACK_SIZE=10240
    
    CONFIG_DEBUG_OPTIMIZATIONS=y
    
    # Enable flash operations
    CONFIG_FLASH=y
    
    # This must be increased to accommodate the bigger images.
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16

    And then in your main code reference:

    #define STORAGE_PARTITION       storage_partition
    #define STORAGE_PARTITION_ID        FIXED_PARTITION_ID(STORAGE_PARTITION)
    This should bring up the flash drive when you program in all the above. Here is my partition manager report for reference:
      external_flash (0x800000 - 8192kB): 
    +----------------------------------------------+
    | 0x0: external_flash (0x780000 - 7680kB)      |
    | 0x780000: settings_storage (0x80000 - 512kB) |
    +----------------------------------------------+
    
      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) |
    +--------------------------------------------+
    Kind Regards
    Julian
  • Hi Julian,

    My apology for the long wait. Please know that I am still around. However, I am still recovering from the high loading time and still haven't been able to look into it yet. There is a holiday here next week, so it will be another high loading wave and some days off, but I will try to get to this as soon as I can.

    Best regards,

    Hieu

  • Hi Hieu,

    Not a problem at all. I appreciate the update. Hopefully you can have a bit of break with the public holiday.

    Kind Regards

    Julian

  • I haven't read through all of this case but could this solution be of help to you:

    As this is merged: https://github.com/nrfconnect/sdk-nrf/pull/11802/ disk access API with partition manager will be resolved in the NCS 2.5 release. However if you want to start testing it out you can cherry-pick this patch.

    I made a prototype implementation for how you could potentially integrate parts of this into the build system see:
    https://github.com/sigvartmh/fw-nrfconnect-nrf-1/pull/38/

    and here is the diff to the MSC sample in zephyr:

    diff --git a/samples/subsys/usb/mass/prj.conf b/samples/subsys/usb/mass/prj.conf
    index 0954afcd0e..a8bc60848d 100644
    --- a/samples/subsys/usb/mass/prj.conf
    +++ b/samples/subsys/usb/mass/prj.conf
    @@ -12,3 +12,4 @@ CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
     CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    
     CONFIG_MAIN_STACK_SIZE=1536
    +CONFIG_PM_PARTITION_FATFS_DISK_NAME="NAND"
    diff --git a/samples/subsys/usb/mass/src/main.c b/samples/subsys/usb/mass/src/main.c
    index 0d8d6ba982..b40681ef76 100644
    --- a/samples/subsys/usb/mass/src/main.c
    +++ b/samples/subsys/usb/mass/src/main.c
    @@ -28,8 +28,8 @@ LOG_MODULE_REGISTER(main);
     FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
     #endif
    
    -#define STORAGE_PARTITION              storage_partition
    -#define STORAGE_PARTITION_ID           FIXED_PARTITION_ID(STORAGE_PARTITION)
    +#define STORAGE_PARTITION              fatfs_storage
    +#define STORAGE_PARTITION_ID           FIXED_PARTITION_ID(FATFS_STORAGE)
    
     static struct fs_mount_t fs_mnt;

  • Just wanted to say that this was extremely useful for me to get over the exact same problem. So thanks for taking the time to post this. 

Related