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!
Parents
  • Hi,

    Which version of nRF Connect SDK are you using?

    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?

    I will have to look closer into this.

    2/ serial DFU (virtual com port on USB) vs USB DFU : which is better to use? Which gives me a smaller mcuboot image?

    Which is better to use: That depends on the design of your product. W.r.t to size you would have to build your project for either configurations and see the build results.

    3/ Image size : mcuboot with DFU_USB is now 76+Kb
    Is this normal?

    If you've done optimizations, then that might be the default size, yes. Without DFU_USB MCUboot defaults to 48kB, but can be shrunk depending on what features you need.

    Are there ways to slim this down?

    The optimization page here might give you some more information w.r.t shrinking the size of the bootloader: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/test_and_optimize.html 

    In addition you can have a look at the minimal mcuboot confiugration such as discussed here in the Matter applications: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/end_product/bootloader.html 

    also, the mcuboot child_image build has its own mcuboot.conf - does this addon to the usual prj.conf, or replace it completely?

    If my understanding is correct it adds configurations that are just defined for said child image (MCUboot in this case).

    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....

    The optimization links as well as this https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf70/fw_patches_ext_flash.html and to use external flash for general DFU (which I assume you already do) is hopefully a good starting place, but let me know if you have any more specific questions.

    Kind regards,
    Andreas

  • Which version of nRF Connect SDK are you using?

    2.6.x

    2/ serial DFU (virtual com port on USB) vs USB DFU : which is better to use? Which gives me a smaller mcuboot image?

    Which is better to use: That depends on the design of your product. W.r.t to size you would have to build your project for either configurations and see the build results.

    Yes, I was rather hoping for some experience rather than having to explore all the possible options myself... But hving tried the 'USB DFU' option, I have decided against, as it requires installing the WinUSB driver for the device to let dfu-util see it, but this then breaks the USB FS operation (at least on my PC)...

    Trying serial DFU, but it doesn't like my dfu zip it seems: 

    This is the zip created directly by the west build. Any idea what it is objecting to?

    In addition you can have a look at the minimal mcuboot confiugration such as discussed here in the Matter applications: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/end_product/bootloader.html

    This claims you can get down to 24kB. I have managed to reduce the basic mcuboot to about 40kB, but with the serial loader option it is still up at over 64kB... 

    The optimization links as well as this https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf70/fw_patches_ext_flash.html and to use external flash for general DFU (which I assume you already do) is hopefully a good starting place, but let me know if you have any more specific questions.

    Yes, my DFU secondary slots are in the external flash already.

    I will need to try to "nrf7002 firmware in external flash" option, even if it looks complex, as that will save 64kB I guess.

    I have switched to tinyCrypt instead of mbedtls, which seems to save some 30kB or so. However, I haven't managed (with either) to get a TLS connection (for https) to work yet... what are the impacts of using tinyCrypt?

  • Hi,

    BrianW said:
    This is the zip created directly by the west build. Any idea what it is objecting to?

    Could you use the generated app_update.bin instead of the zip? https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/config_and_build/output_build_files.html 

    BrianW said:
    This claims you can get down to 24kB. I have managed to reduce the basic mcuboot to about 40kB, but with the serial loader option it is still up at over 64kB... 

    Is the 64kB with or without logging?

    BrianW said:
    I will need to try to "nrf7002 firmware in external flash" option, even if it looks complex, as that will save 64kB I guess.

    As far as I know it should be relatively straight forward, but feel free to ask questions if you're stuck at any point with this.

    BrianW said:
    I have switched to tinyCrypt instead of mbedtls, which seems to save some 30kB or so. However, I haven't managed (with either) to get a TLS connection (for https) to work yet... what are the impacts of using tinyCrypt?

    I fear that this question might be a full case in itself. Could you create a new case for your questions regarding crypto?

    Kind regards,
    Andreas

  • Well, this is what I use for DFU target updates, but nrfutil says:

    zipfile.BadZipFile: File is not a zip file

    (and I have to agree!)

    This claims you can get down to 24kB. I have managed to reduce the basic mcuboot to about 40kB, but with the serial loader option it is still up at over 64kB... 

    Is the 64kB with or without logging?

    Without logging. Here's the conf for mcuboot which gives me >64kB.. If I turn off MCUBOOT_SERIAL and BOOT_SERIAL_CDC_ACM then its about 40kB (and with logs 48kB)

    # mcuboot serial recovery makes image too big for flash space... TODO find more space
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    # Enable wait for DFU functionality at boot? 
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=n
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=5000
    
    # DFU directly as special USB device? - nO, this required winusb zadig driver which then broke usb FS mounting...
    CONFIG_BOOT_USB_DFU_WAIT=n
    CONFIG_BOOT_USB_DFU_WAIT_DELAY_MS=5000
    #CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Infrafon CC2-WDD"
    # USB VID is MCS electronics, who sell individual PIDs. 0x138F is for CC2 purchases 25/08/2024
    CONFIG_USB_DEVICE_VID=0x16D0
    CONFIG_USB_DEVICE_PID=0x138F
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n
    
    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_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    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
    
    CONFIG_DEBUG=n
    CONFIG_DEBUG_INFO=n
    # all functions in seperate sections so linker can discard unused code
    CONFIG_COMPILER_OPT="-Os"
    # -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--strip-all"
    CONFIG_THREAD_NAME=n
    CONFIG_THREAD_ANALYZER=n
    CONFIG_THREAD_ANALYZER_USE_PRINTK=n
    CONFIG_THREAD_ANALYZER_AUTO=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
    
    # turn off serial and uart console to save space (later)
    CONFIG_CONSOLE=n
    CONFIG_CONSOLE_HANDLER=n
    CONFIG_SERIAL=n
    CONFIG_UART_CONSOLE=n
    CONFIG_STDOUT_CONSOLE=n
    
    # turn off log to save image size
    CONFIG_LOG=n
    CONFIG_LOG_MODE_MINIMAL=y
    CONFIG_LOG_MODE_IMMEDIATE=n
    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_GPIO=n
    CONFIG_GPIO_MCP230XX=n
    
    CONFIG_USE_SEGGER_RTT=n
    CONFIG_I2C=n
    CONFIG_SPI=n
    
    CONFIG_BOOT_BANNER=n
    #CONFIG_TIMESLICING=n
    #CONFIG_MULTITHREADING=n
    CONFIG_TICKLESS_KERNEL=n
    CONFIG_TIMEOUT_64BIT=n
    CONFIG_NRF_ENABLE_ICACHE=n
    

    BrianW said:
    I have switched to tinyCrypt instead of mbedtls, which seems to save some 30kB or so. However, I haven't managed (with either) to get a TLS connection (for https) to work yet... what are the impacts of using tinyCrypt?

    I fear that this question might be a full case in itself. Could you create a new case for your questions regarding crypto?

    Ok, will do.

Reply
  • Well, this is what I use for DFU target updates, but nrfutil says:

    zipfile.BadZipFile: File is not a zip file

    (and I have to agree!)

    This claims you can get down to 24kB. I have managed to reduce the basic mcuboot to about 40kB, but with the serial loader option it is still up at over 64kB... 

    Is the 64kB with or without logging?

    Without logging. Here's the conf for mcuboot which gives me >64kB.. If I turn off MCUBOOT_SERIAL and BOOT_SERIAL_CDC_ACM then its about 40kB (and with logs 48kB)

    # mcuboot serial recovery makes image too big for flash space... TODO find more space
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    # Enable wait for DFU functionality at boot? 
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=n
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=5000
    
    # DFU directly as special USB device? - nO, this required winusb zadig driver which then broke usb FS mounting...
    CONFIG_BOOT_USB_DFU_WAIT=n
    CONFIG_BOOT_USB_DFU_WAIT_DELAY_MS=5000
    #CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Infrafon CC2-WDD"
    # USB VID is MCS electronics, who sell individual PIDs. 0x138F is for CC2 purchases 25/08/2024
    CONFIG_USB_DEVICE_VID=0x16D0
    CONFIG_USB_DEVICE_PID=0x138F
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n
    
    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_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    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
    
    CONFIG_DEBUG=n
    CONFIG_DEBUG_INFO=n
    # all functions in seperate sections so linker can discard unused code
    CONFIG_COMPILER_OPT="-Os"
    # -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--strip-all"
    CONFIG_THREAD_NAME=n
    CONFIG_THREAD_ANALYZER=n
    CONFIG_THREAD_ANALYZER_USE_PRINTK=n
    CONFIG_THREAD_ANALYZER_AUTO=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
    
    # turn off serial and uart console to save space (later)
    CONFIG_CONSOLE=n
    CONFIG_CONSOLE_HANDLER=n
    CONFIG_SERIAL=n
    CONFIG_UART_CONSOLE=n
    CONFIG_STDOUT_CONSOLE=n
    
    # turn off log to save image size
    CONFIG_LOG=n
    CONFIG_LOG_MODE_MINIMAL=y
    CONFIG_LOG_MODE_IMMEDIATE=n
    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_GPIO=n
    CONFIG_GPIO_MCP230XX=n
    
    CONFIG_USE_SEGGER_RTT=n
    CONFIG_I2C=n
    CONFIG_SPI=n
    
    CONFIG_BOOT_BANNER=n
    #CONFIG_TIMESLICING=n
    #CONFIG_MULTITHREADING=n
    CONFIG_TICKLESS_KERNEL=n
    CONFIG_TIMEOUT_64BIT=n
    CONFIG_NRF_ENABLE_ICACHE=n
    

    BrianW said:
    I have switched to tinyCrypt instead of mbedtls, which seems to save some 30kB or so. However, I haven't managed (with either) to get a TLS connection (for https) to work yet... what are the impacts of using tinyCrypt?

    I fear that this question might be a full case in itself. Could you create a new case for your questions regarding crypto?

    Ok, will do.

Children
Related