DFU using USB file system (not serial emulation)?

My project has a nrf5340+external flash, and an external USB-C connector. The device exposes a USB file system (FAT) which is hosted on the external flash partition, and appears as an external disk when connected to a host. This all works well and is used to update config, image files etc for the device to use.

I would like to be able to do application / network firmware updates by simply copying the new image (hex or bin) to this file system and rebooting. Has anyone done this? I'm guessing it involves using MCUBoot bootloader and copying the image into the secondary image slot somehow? I also want to put the secondard image slot on my external flash as won't have space on the internal flash - even better would be if MCUBoot could take the image directly from the file in the FS....

by the way, to be clear, I do NOT want to use the 'DFU over USB serial emulation' method, as this requires the user to install the specific tool to the host machine, which may not be available for their host or may not be allowed by IT policy (or by their level of expertise...). 

thanks for any pointers!

  • Hi Brian, 
    I haven't done this myself but as far as I know MCUBoot doesn't handle the process of receiving the image. What it does when booting is to check the configured partition to see if there is a image candidate that need to be swapped. If there is it will perform the task. The MCUBoot doesn't involve in how you receive the image. 

    You job is to point the MCUBoot to the correct partition that has the image and the trailer.

     
    There were an issue in the past with Partition Manager and FATFS, but from what I can find it's been fixed. 
    Could you take a look at this ticket and check if it provide a solution for you: Mass storage initialization error with nsib and mcuboot 

  • Hi,

    The issue you pointed to is fixed I think - I have my USB FAT-FS running fine in the external flash chip (with partition manager doing the inernal flash layout)

    my pm_static.yml file : (this might help others, it took a bit of work to get to this setup for the USB FS!)

    # define partition for fatfs disk, on the external flash storage (probably the device defined by nordic,pm-ext-flash in the DTS)
    fatfs_storage:
        region: external_flash
        affiliation:
            - disk
        extra_params: {
            disk_name: "NAND",
            disk_cache_size: 4096,
            disk_sector_size: 512,
            disk_read_only: 0
        }
        placement:
            after: [start]
            align: {start: 4096}
        # 6Mb size, external flash is 8Mb total
        address: 0x0
        size: 0x600000

    nvs_storage:
        region: external_flash
        affiliation:
            - nvs
        # 64kB size, its just for small stuff
        address: 0x600000
        size: 0x10000

    mcuboot_secondary1:
        region: external_flash
        affiliation:
            - mcuboot
        # 256kb size, its for netcore flash image
        address: 0x610000
        size: 0x40000

    mcuboot_secondary:
        region: external_flash
        affiliation:
            - mcuboot
        # 1Mb size, its for an application flash image
        address: 0x650000
        size: 0xF4000

    My assumption is that I just need to take the hex file from the USB FS part, and copy it into the mcuboot_secondary (for the app part) and mcuboot_secondary1 (for the net part). 

    My original question is then : how to do this?

    However...this gives me a output partition like this with MCUBoot deactivated:

    app:
      address: 0x0
      end_address: 0x100000
      region: flash_primary
      size: 0x100000
    external_flash:
      address: 0x744000
      end_address: 0x800000
      region: external_flash
      size: 0xbc000
    fatfs_storage:
      address: 0x0
      affiliation:
      - disk
      end_address: 0x600000
      extra_params:
        disk_cache_size: 0x1000
        disk_name: NAND
        disk_read_only: 0x0
        disk_sector_size: 0x200
      placement:
        after:
        - start
        align:
          start: 0x1000
      region: external_flash
      size: 0x600000
    mcuboot_secondary:
      address: 0x650000
      affiliation:
      - mcuboot
      end_address: 0x744000
      region: external_flash
      size: 0xf4000
    mcuboot_secondary1:
      address: 0x610000
      affiliation:
      - mcuboot
      end_address: 0x650000
      region: external_flash
      size: 0x40000
    nvs_storage:
      address: 0x600000
      affiliation:
      - nvs
      end_address: 0x610000
      region: external_flash
      size: 0x10000
    otp:
      address: 0xff8100
      end_address: 0xff83fc
      region: otp
      size: 0x2fc
    rpmsg_nrf53_sram:
      address: 0x20070000
      end_address: 0x20080000
      placement:
        before:
        - end
      region: sram_primary
      size: 0x10000
    sram_primary:
      address: 0x20000000
      end_address: 0x20070000
      region: sram_primary
      size: 0x70000
     
    However, when I enabled MCUboot, the build fails with this error:
    -- Found partition manager static configuration: C:/work/dev/if-device-nrf53/cc1-med/pm_static.yml
    Partition 'nvs_storage' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_secondary' is not included in the dynamic resolving since it is statically defined.
    -- Configuring done
    -- Generating done
    -- Build files have been written to: C:/work/dev/if-device-nrf53/cc1-med/build
    -- west build: building application
    [11/666] Performing build step for 'mcuboot_subimage'
    [3/279] Generating include/generated/version.h
    -- Zephyr version: 3.5.99 (C:/work/dev/nordic_connect/zephyr), build: 3758bcbfa5cd
    [274/279] Linking C executable zephyr\zephyr_pre0.elf
    FAILED: zephyr/zephyr_pre0.elf zephyr/zephyr_pre0.map C:/work/dev/if-device-nrf53/cc1-med/build/mcuboot/zephyr/zephyr_pre0.map
    cmd.exe /C "cd . && C:\ncs\toolchains\cf2149caf2\opt\zephyr-sdk\arm-zephyr-eabi\bin\arm-zephyr-eabi-gcc.exe -gdwarf-4 zephyr/CMakeFiles/zephyr_pre0.dir/misc/empty_file.c.obj -o zephyr\zephyr_pre0.elf zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj -fuse-ld=bfd -T zephyr/linker_zephyr_pre0.cmd -Wl,-Map=C:/work/dev/if-device-nrf53/cc1-med/build/mcuboot/zephyr/zephyr_pre0.map -Wl,--whole-archive app/libapp.a zephyr/libzephyr.a zephyr/arch/common/libarch__common.a zephyr/arch/arch/arm/core/libarch__arm__core.a zephyr/arch/arch/arm/core/cortex_m/libarch__arm__core__cortex_m.a zephyr/arch/arch/arm/core/cortex_m/cmse/libarch__arm__core__cortex_m__cmse.a zephyr/arch/arch/arm/core/mpu/libarch__arm__core__mpu.a zephyr/lib/libc/minimal/liblib__libc__minimal.a zephyr/lib/libc/common/liblib__libc__common.a zephyr/soc/soc/arm/nordic_nrf/libsoc__arm__nordic_nrf.a zephyr/drivers/clock_control/libdrivers__clock_control.a zephyr/drivers/console/libdrivers__console.a zephyr/drivers/flash/libdrivers__flash.a zephyr/drivers/gpio/libdrivers__gpio.a zephyr/drivers/pinctrl/libdrivers__pinctrl.a zephyr/drivers/serial/libdrivers__serial.a zephyr/drivers/timer/libdrivers__timer.a modules/nrf/lib/fprotect/lib..__nrf__lib__fprotect.a modules/nrf/lib/fatal_error/lib..__nrf__lib__fatal_error.a modules/nrf/subsys/pcd/lib..__nrf__subsys__pcd.a modules/nrf/drivers/hw_cc3xx/lib..__nrf__drivers__hw_cc3xx.a modules/mcuboot/boot/bootutil/zephyr/libmcuboot_util.a modules/mbedtls/libmbedTLSBase.a modules/mbedtls/libmbedTLSCrypto.a modules/mbedtls/libmbedTLSX509.a modules/mbedtls/libmodules__mbedtls.a modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a -Wl,--no-whole-archive zephyr/kernel/libkernel.a -L"c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/thumb/v8-m.main/nofp" -LC:/work/dev/if-device-nrf53/cc1-med/build/mcuboot/zephyr -lgcc zephyr/arch/common/libisr_tables.a modules/mbedtls/libmbedTLSBase.a modules/mbedtls/libmbedTLSCrypto.a modules/mbedtls/libmbedTLSX509.a -mcpu=cortex-m33 -mthumb -mabi=aapcs -mfp16-format=ieee -Wl,--gc-sections -Wl,--build-id=none -Wl,--sort-common=descending -Wl,--sort-section=alignment -Wl,-u,_OffsetAbsSyms -Wl,-u,_ConfigAbsSyms -nostdlib -static -Wl,-X -Wl,-N -Wl,--orphan-handling=warn -Wl,-no-pie C:/work/dev/nordic_connect/nrfxlib/crypto/nrf_cc312_platform/lib/cortex-m33/soft-float/no-interrupts/libnrf_cc312_platform_0.9.19.a && cmd.exe /C "cd /D C:\work\dev\if-device-nrf53\cc1-med\build\mcuboot\zephyr && C:\ncs\toolchains\cf2149caf2\opt\bin\cmake.exe -E true""
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: zephyr\zephyr_pre0.elf section `rodata' will not fit in region `FLASH'
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: region `FLASH' overflowed by 4552 bytes
    collect2.exe: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.

    Which region FLASH is overflowed? app or net? the app  code is not yet compiled at this stage of the build so how does it know??

    thanks for pointers on getting it to build with mcuboot included....

  • by the way, if I build without MCUBoot (but same pm_static.yml etc), then the linkertells me:

    [0/130] Performing build step for 'hci_ipc_subimage'
    [13/15] Linking C executable zephyr\zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH: 177 KB 256 KB 69.14%
    RAM: 48700 B 64 KB 74.31%
    SRAM1: 0 GB 64 KB 0.00%
    IDT_LIST: 0 GB 32 KB 0.00%
    [15/15] Generating zephyr/merged_CPUNET.hex
    [122/128] Linking C executable zephyr\zephyr_pre0.elf
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: warning: orphan section `.fonts' from `app/libapp.a(u8g2_fonts.c.obj)' being placed in section `.fonts'
    [126/128] Linking C executable zephyr\zephyr.elf
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: warning: orphan section `.fonts' from `app/libapp.a(u8g2_fonts.c.obj)' being placed in section `.fonts'
    Memory region Used Size Region Size %age Used
    FLASH: 1017927 B 1 MB 97.08%
    RAM: 219248 B 448 KB 47.79%
    IDT_LIST: 0 GB 32 KB 0.00%
    [128/128] Generating zephyr/merged_domains.hex

  • Hi Brian, 
    Have you located flash space for MCUBoot it self? It should be located at address 0x0 and the application should be located after the MCUBoot partition. Please try to compile a sample with MCUboot included. You can check the partitions.yml generated to have an idea. 
    I attached here an example, it was from SDK v2.3 but it shouldn't be much change for the new SDK.
    https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/partitions.yml

  • that partitions.yml looks similar to what my PM generates. I use a pm_static.yml file for the external flash, and let the PM do the internal one. Partition sizes look the same, for mcu boot and for app..

    It seems the problem is not the cpunet : this gets generated ok and fits in its flash partitions (generated by PM or by magic...)

    [11/666] Performing build step for 'hci_ipc_subimage'
    [0/222] Generating signing key
    [2/222] Creating public key from private key used for signing
    [6/222] Creating data to be provisioned to the Bootloader, storing to provision.hex
    [9/222] Performing build step for 'b0n_subimage'
    [2/137] Generating include/generated/version.h
    -- Zephyr version: 3.5.99 (C:/work/dev/nordic_connect/zephyr), build: 3758bcbfa5cd
    [137/137] Linking C executable zephyr\zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH: 23710 B 34176 B 69.38%
    RAM: 3528 B 64 KB 5.38%
    SRAM1: 0 GB 64 KB 0.00%
    IDT_LIST: 0 GB 32 KB 0.00%
    [10/222] Generating include/generated/version.h
    -- Zephyr version: 3.5.99 (C:/work/dev/nordic_connect/zephyr), build: 3758bcbfa5cd
    [218/222] Linking C executable zephyr\zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH: 181952 B 222 KB 80.04%
    RAM: 48700 B 64 KB 74.31%
    SRAM1: 0 GB 64 KB 0.00%
    IDT_LIST: 0 GB 32 KB 0.00%
    [219/222] Creating signature of application
    [220/222] Creating validation for zephyr.hex, storing to
    [222/222] Generating zephyr/merged_CPUNET.hex

    So I guess the problem is with the main app flash size... it complains twice:

    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: zephyr\zephyr_pre0.elf section `rodata' will not fit in region `FLASH'
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: region `FLASH' overflowed by 4552 bytes

    ... and then ...

    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: warning: orphan section `.fonts' from `app/libapp.a(u8g2_fonts.c.obj)' being placed in section `.fonts'
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: zephyr\zephyr_pre0.elf section `.fonts' will not fit in region `FLASH'
    c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: region `FLASH' overflowed by 21223 bytes

    I'm kind of surprised but maybe my main app is too large for the 'app' partition now its squeezed by mcuboot (but only about 50kb from 990kB, so thats unlikely??)

Related