Size of build image for mcuboot with serial or usb DFU enabled?

Working on a nrf5340 project, and running into limits of the size of the flash to store my application image along with mcuboot bootloader.

I had a mucboot setup that fitted into 56Kb (signed images, secondary slot on external flash). This did NOT include the serial DFU however, and (of course) one of my first units out in the field got bricked during a DFU (using dfu_target lib to update the secondary slot from a file loaded on USB FAT FS mounted on the external flash... not yet got the unit to see what got corrupted...)

I expose the USB interface, so would like to enable the serial DFU functionality in mcuboot so that at least I have a method to DFU even if my main app image gets corrupted...Some questions to get this to work:

1/ The buttons on the device are via a gpio expander on the i2c interface, it seems mcuboot likes a 'dfu button' to be a direct gpio (at least if I set the alias:

mcuboot-button0 = &button2;
then it doesn't build because button2 is 
button2: button_2 {
            gpios = <&ioexp0 4 (GPIO_ACTIVE_LOW)>;    // GPA4
). Is this correct or should it work via a ioexpander?
BTW This is not a deal breaker as I see I can have a 'DFU delay' at boot to always check if the dfu is to be activated on the serial/USB
2/ serial DFU (virtual com port on USB) vs USB DFU : which is better to use? Which gives me a smaller mcuboot image?
3/ Image size : mcuboot with DFU_USB is now 76+Kb
Is this normal? Are there ways to slim this down? also, the mcuboot child_image build has its own mcuboot.conf - does this addon to the usual prj.conf, or replace it completely?
The image size is an issue because my main app uses https over wifi networking (nrf7002) and the wifi code+networking+TLS takes up a LOT of space....
thanks for any tips to get a solid mcuboot in the least flash space!
  • just to help anoyone else, here's my pm_static.yml and prj.conf for mcuboot (for sysbuild use). 

    pm_static.yml

    mcuboot:
        address: 0x0
        end_address: 0x11000
        region: flash_primary
        affiliation: 
            - mcuboot
        size: 0x11000
    
    mcuboot_pad:
        # should be aligned on CONFIG_FPROTECT_BLOCK_SIZE (0x4000 on nrf5340) boundry to allow FPROTECT to be enabled
        # and AT minimum on 0x1000 sector size for erase needs (otherwise DFU (move algo) will NOT WORK)
        address: 0x11000
        end_address: 0x11200
        region: flash_primary
        affiliation: 
            - mcuboot
        size: 0x200
    
    app:
        address: 0x11200
        end_address: 0x100000
        region: flash_primary
        size: 0xeee00
    
    mcuboot_primary_app:
        address: 0x11200
        end_address: 0x100000
        region: flash_primary
        affiliation: 
            - mcuboot
        size: 0xeee00
        span: [app]
    
    mcuboot_primary:
        address: 0x11000
        end_address: 0x100000
        region: flash_primary
        affiliation: 
            - mcuboot
        size: 0xef000
        span: [mcuboot_pad, app]
    
    # 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
        }
        # 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_secondary_1:
        region: external_flash
        affiliation: 
            - mcuboot
        # 256kb size, its for netcore flash image
        address: 0x610000
        size: 0x40000
    
    mcuboot_secondary:
        region: external_flash
        affiliation: 
            - mcuboot
        address: 0x650000
        # MUST be same size as the 'mcuboot_primary' slot size, and share_size does not appear to work
        size: 0xef000
        #share_size: [mcuboot_primary]
    
    # get next slot to be aligned on 0x4000
    PAD1_END:
        region: external_flash
        address: 0x73f000
        size: 0x1000
    
    # allow wifi patches to be updated by mcuboot
    nrf70_wifi_fw_mcuboot_pad:
        region: external_flash
        address: 0x740000
        size: 0x200
        #device: MX25R64
    
    nrf70_wifi_fw:
        region: external_flash
        # 128kB size for the wifi fw (-0x200 bytes, the mcuboot pad so that total is aligned on 0x1000 - and 0x4000 - to keep mcuboot happy), 
        address: 0x740200
        size: 0x1fe00
    
    mcuboot_primary_2:
        region: external_flash
        orig_span: &id003
        - nrf70_wifi_fw_mcuboot_pad
        - nrf70_wifi_fw
        span: *id003
        address: 0x740000
        affiliation: 
            - mcuboot
        size: 0x20000
        #device: MX25R64
    
    mcuboot_secondary_2:
        region: external_flash
        address: 0x760000
        affiliation: 
            - mcuboot
        size: 0x20000
        #device: MX25R64
    
    # remaining external flash space starts at 0x78000
    
    # need fake flash ram flash partition to do cpunet DFU...
    mcuboot_primary_1:
        region: ram_flash
        address: 0x0
        affiliation: 
            - mcuboot
        size: 0x40000
        device: flash_ctrl
        #  end_address: 0x40000
        #  device: nordic_ram_flash_controller
    
    ram_flash:
      address: 0x40000
      end_address: 0x40000
      region: ram_flash
      size: 0x0
    
    # internal cuisine
    #otp:
    #    address: 0xff8100
    #    end_address: 0xff83fc
    #    region: otp
    #    size: 0x2fc
    #pcd_sram:
    #    address: 0x20000000
    #    end_address: 0x20002000
    #    region: sram_primary
    #    size: 0x2000
    #rpmsg_nrf53_sram:
    #    address: 0x20070000
    #    end_address: 0x20080000
    #    region: sram_primary
    #    size: 0x10000
    #sram_primary:
    #    address: 0x20002000
    #    end_address: 0x20070000
    #    region: sram_primary
    #    size: 0x6e000
    
    

    sysbuild/mcuboot/proj.conf

    CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot"
    
    CONFIG_FLASH=y
    
    # Want the following functionality, but to fit in 64kB!
    # Want the following functionality, but to fit in 64kB!
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    CONFIG_BOOT_SERIAL_NO_APPLICATION=y
    CONFIG_USB_DEVICE_MANUFACTURER="Acme Ltd"
    CONFIG_USB_DEVICE_PRODUCT="CC2"
    # USB VID is MCS electronics, who sell individual PIDs. Cheap to get a PID...
    CONFIG_USB_DEVICE_VID=0x16D0
    CONFIG_USB_DEVICE_PID=0x1234
    # no functional need for USB HID emulation (and its a big chunk of code)
    CONFIG_USB_DEVICE_HID=n
    CONFIG_USB_MASS_STORAGE=n
    
    CONFIG_BOOT_MAX_LINE_INPUT_LEN=8192
    CONFIG_BOOT_SERIAL_MAX_RECEIVE_SIZE=4096
    #CONFIG_CDC_ACM_BULK_EP_MPS=512
    
    # DFU by holding down a button at boot time (mcuboot-button0 alias in DTS)
    CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=y
    CONFIG_MCUBOOT_INDICATION_LED=y
    
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    #FPROTECT is n as current primary pad is not aligned on 0x4000 boundary
    CONFIG_FPROTECT=n
    CONFIG_BOOT_BOOTSTRAP=y
    # want to update CPU-NET image
    # not allowed with sysbuild CONFIG_NETCORE_APP_UPDATE=y
    
    CONFIG_MAIN_STACK_SIZE=10240
    # Set QSPI flash layout configuration
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    
    # Now in sysbuild.conf
    #CONFIG_BOOTLOADER_MCUBOOT=y
    #CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    #CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_BOOT_SWAP_USING_MOVE=y
    
    # allow update of CPU-NET image (image 1)
    #CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH=y
    #CONFIG_NRF53_UPGRADE_NETWORK_CORE=y
    #CONFIG_ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS=y
    # The network core cannot access external flash directly. The flash simulator must be used to
    # provide a memory region that is used to forward the new firmware to the network core.
    CONFIG_FLASH_SIMULATOR=y
    CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
    CONFIG_FLASH_SIMULATOR_STATS=n
    
    CONFIG_MCUBOOT_SHELL=n
    
    CONFIG_DEBUG_COREDUMP=n
    CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=n
    CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=n
    
    # Use minimal C library instead of the Picolib
    CONFIG_MINIMAL_LIBC=y
    ### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y
    CONFIG_CBPRINTF_NANO=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=n
    
    #CONFIG_BOOT_ECDSA_TINYCRYPT=y
    
    CONFIG_DEBUG=n
    CONFIG_DEBUG_INFO=n
    
    CONFIG_THREAD_NAME=n
    CONFIG_THREAD_ANALYZER=n
    CONFIG_SYS_HEAP_RUNTIME_STATS=n
    CONFIG_INIT_STACKS=n
    CONFIG_ASSERT=n
    CONFIG_ASSERT_VERBOSE=n
    CONFIG_ASSERT_NO_MSG_INFO=y
    CONFIG_ASSERT_NO_COND_INFO=y
    CONFIG_ASSERT_NO_FILE_INFO=y
    CONFIG_STACK_SENTINEL=n
    CONFIG_RESET_ON_FATAL_ERROR=y
    CONFIG_REBOOT=y
    
    # could turn off serial and uart console to save space when no logging required... but need them on to get printk()
    CONFIG_CONSOLE=y
    CONFIG_CONSOLE_HANDLER=n
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=y
    CONFIG_STDOUT_CONSOLE=y
    
    # turn off log to save image size
    CONFIG_LOG=n
    CONFIG_LOG_MODE_MINIMAL=n
    # BUT hack in bootloader/mcuboot/boot/bootutil/include/bootutil/bootutil_log.h to send logs to printk() directly
    
    #CONFIG_LOG_MODE_IMMEDIATE=y
    #CONFIG_LOG_BACKEND_UART=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_LOG_PRINTK=n
    CONFIG_SHELL=n
    CONFIG_SHELL_MINIMAL=n
    
    CONFIG_SHELL_LOG_BACKEND=n
    CONFIG_NCS_SAMPLES_DEFAULTS=n
    CONFIG_NO_RUNTIME_CHECKS=y
    
    CONFIG_MBEDTLS_LOG_LEVEL_ERR=y
    CONFIG_KERNEL_LOG_LEVEL_ERR=y
    CONFIG_I2C_LOG_LEVEL_ERR=y
    CONFIG_GPIO_LOG_LEVEL_ERR=y
    CONFIG_UART_LOG_LEVEL_ERR=y
    CONFIG_PINCTRL_LOG_LEVEL_ERR=y
    CONFIG_FLASH_LOG_LEVEL_ERR=y
    # only enable error level logs for usb, as lots of warnings....
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    
    CONFIG_GPIO=y
    CONFIG_I2C=y
    CONFIG_GPIO_MCP230XX=y
    
    CONFIG_BT=n
    CONFIG_WIFI=n
    CONFIG_NFC_T2T_NRFXLIB=n
    CONFIG_NFC_T4T_NRFXLIB=n
    CONFIG_NFC_T4T_ISODEP=n
    CONFIG_NFC_NDEF=n
    CONFIG_USE_SEGGER_RTT=n
    CONFIG_SPI=n
    CONFIG_I2S=n
    CONFIG_PWM=n
    CONFIG_CJSON_LIB=n
    CONFIG_JSON_LIBRARY=n
    CONFIG_APP_EVENT_MANAGER=n
    CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0
    
    CONFIG_BOOT_BANNER=n
    CONFIG_TICKLESS_KERNEL=n
    CONFIG_TIMEOUT_64BIT=n
    CONFIG_NRF_ENABLE_ICACHE=n
    
    # Enable LTO
    CONFIG_ISR_TABLES_LOCAL_DECLARATION=y
    CONFIG_LTO=y
    

    and the sysbuild.conf for completeness

    # MCU boot config now handled by sysbuild
    SB_CONFIG_BOOTLOADER_MCUBOOT=y
    
    # build HCI-IPC image for CPU-NET
    SB_CONFIG_NETCORE_HCI_IPC=y
    
    # we allow secure update of images, but not of mcuboot itself.
    # allow update of CPU-NET
    SB_CONFIG_SECURE_BOOT_NETCORE=y
    SB_CONFIG_NETCORE_APP_UPDATE=y
    
    SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="\${APPLICATION_CONFIG_DIR}/../keys/bootloader_priv-ecdsa256.pem"
    #SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #SB_CONFIG_SECURE_BOOT_SIGNING_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    SB_CONFIG_SECURE_BOOT_SIGNING_KEY_FILE="\${APPLICATION_CONFIG_DIR}/../keys/bootloader_priv-ecdsa256.pem"
    
    SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH=y
    
    # nrf7002 firmware handled by sysbuild
    SB_CONFIG_WIFI_NRF70=y
    SB_CONFIG_WIFI_NRF70_SYSTEM_MODE=y
    SB_CONFIG_WIFI_PATCHES_EXT_FLASH_STORE=y
    
    SB_CONFIG_MCUBOOT_UPDATEABLE_IMAGES=3
    #SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER=0
    #SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER=1
    #SB_CONFIG_MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER=2
    
    # build of dfu packages
    #SB_CONFIG_SUPPORT_NETCORE=y
    #SB_CONFIG_SECURE_BOOT=y
    #SB_CONFIG_SECURE_BOOT_NETCORE=y
    
    #SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_BUILD=y
    #SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_APP=y
    #SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_NET=y
    #SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_WIFI_FW_PATCH=y
    
    #SB_CONFIG_DFU_ZIP=y
    #SB_CONFIG_DFU_ZIP_APP=y
    #SB_CONFIG_DFU_ZIP_NET=y
    #SB_CONFIG_DFU_ZIP_WIFI_FW_PATCH=y
    
    # put application secondary slot in external flash
    SB_CONFIG_PARTITION_MANAGER=y
    SB_CONFIG_PM_MCUBOOT_PAD=0x200
    SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    

Related