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!

  • I find the error:

    E: Protect mcuboot flash failed, cancel startup.

    is linked to the mcuboot flash protect mechanism.

    Adding 

    CONFIG_FPROTECT=n
    to child_image/mcuboot.conf means my application now runs!
    But... does this mean I have an attempted write to mcuboot's partition, or is it just that this mechanism is not supported?
  • Hi Brian, 
    FPROTECT is the library that use hardware protection peripheral to protect the MCUBoot from being written by the application or external. 
    Here is the code where the error is thrown: 

    /* There is only one instance of MCUBoot */
    #define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS)
    #define PROTECT_ADDR PM_MCUBOOT_ADDRESS
    #endif
    
        rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE);
    
        if (rc != 0) {
            BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup.");
            while (1)
                ;
        }

    Could you check what's the MCUBoot address and the PM_MCUBOOT_PRIMARY_ADDRESS. Please also send us the partitions.yml file in your success build. 

  • From pm.config in the build directory:

    PM_MCUBOOT_OFFSET=0x0

    PM_MCUBOOT_PRIMARY_OFFSET=0xfe00

    This is exactly what I expect given my pm_static.yml which starts like:

    mcuboot:
        address: 0x0
        end_address: 0xfe00
        #placement:
        #  before:
        #  - mcuboot_primary
        region: flash_primary
        size: 0xfe00
    
    mcuboot_pad:
        address: 0xfe00
        end_address: 0x10000
        #placement:
        #  align:
        #    start: 0xfe00
        #  before:
        #  - mcuboot_primary
        region: flash_primary
        size: 0x200
    
    app:
        address: 0x10000
        end_address: 0x100000
        region: flash_primary
        size: 0xf0000
    
    mcuboot_primary_app:
        address: 0x10000
        end_address: 0x100000
        region: flash_primary
        size: 0xf0000
        #  span: *id002
        span: [app]
    
    mcuboot_primary:
        address: 0xfe00
        end_address: 0x100000
        region: flash_primary
        size: 0xf0200
        #  span: *id001
        span: [mcuboot_pad, mcuboot_primary_app]
     

    I don't see how to attach files to a ticket? Simple drag-n-drop tells me the file type yml is not allowed...

    partition_manager_report target gives me:

    external_flash (0x800000 - 8192kB):
    +-------------------------------------------------+
    | 0x0: fatfs_storage (0x600000 - 6144kB) |
    | 0x600000: nvs_storage (0x10000 - 64kB) |
    | 0x610000: mcuboot_secondary_1 (0x40000 - 256kB) |
    | 0x650000: mcuboot_secondary (0xfc000 - 1008kB) |
    | 0x74c000: external_flash (0xb4000 - 720kB) |
    +-------------------------------------------------+
    
    flash_primary (0x100000 - 1024kB):
    +--------------------------------------------------+
    | 0x0: mcuboot (0xfe00 - 63kB) |
    +---0xfe00: mcuboot_primary (0xf0200 - 960kB)------+
    | 0xfe00: mcuboot_pad (0x200 - 512B) |
    +---0x10000: mcuboot_primary_app (0xf0000 - 960kB)-+
    | 0x10000: app (0xf0000 - 960kB) |
    +--------------------------------------------------+
    
    otp (0x2fc - 764B):
    +------------------------------+
    | 0xff8100: otp (0x2fc - 764B) |
    +------------------------------+
    
    sram_primary (0x80000 - 512kB):
    +-----------------------------------------------+
    | 0x20000000: pcd_sram (0x2000 - 8kB) |
    | 0x20002000: sram_primary (0x6e000 - 440kB) |
    | 0x20070000: rpmsg_nrf53_sram (0x10000 - 64kB) |
    +-----------------------------------------------+
    
    CPUNET flash_primary (0x40000 - 256kB):
    +--------------------------------------------+
    +---0x1000000: b0n_container (0x8800 - 34kB)-+
    | 0x1000000: b0n (0x8580 - 33kB) |
    | 0x1008580: provision (0x280 - 640B) |
    +---0x1008800: app (0x37800 - 222kB)---------+
    | 0x1008800: hci_ipc (0x37800 - 222kB) |
    +--------------------------------------------+
    
    CPUNET sram_primary (0x10000 - 64kB):
    +-------------------------------------------+
    | 0x21000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

    which is prettier anyway...

  • So, now that mcuboot is actually bootingmy code (FPROTECT disabled) I have added 

    CONFIG_STREAM_FLASH=y
    CONFIG_STREAM_FLASH_ERASE=y
    CONFIG_DFU_TARGET_STREAM=y
    CONFIG_IMG_MANAGER=y
    CONFIG_DFU_TARGET_MCUBOOT=y
    and using the dfu_target library to copy the contents of app_update.bin to the mcuboot_secondary partition.
    However, it failed with this log
    "Missing stream_buf, call '..set_buf' before '..init"
    as found in dfu_target_mcuboot.c
    I use the dfu_target api as described in the doc
    but it doesn't mention having to set a buffer for mcuboot before the call to dfu_target_init()
    And nowhere in dfu_target.c does it do this?!
    What is the point of having a 'standard' api dfu_target to mask the different 'targets', if app has to explicitly call a target specific function to get it to work? And not described in the doc either?
     
  • Hi again, 

    You can attach file by clicking Insert -> Image/Video/file 

    Or you can add code by Insert -> Code 

    Regarding the mcuboot partition, can you tell why you choose 0xfe00 ( mcuboot end address) and 0x10000 (mcuboot pad end address) ? 
    The problem of this address is that it doesn't allign with FPROTECT_BLOCK_SIZE ( =NRF_SPU_FLASH_REGION_SIZE = 0x4000). 


    Could you try again with 0xc000 and 0xc200 respectively or try 0x10000 and 0x10200 respectively. 

Related