Reducing flash usage and removing unused KConfigs for FOTA

When I build my application for the nrf52833-DK board with the "Optimize for size (-Os)" option, I can see in the terminal that the FLASH Region Size is 237056 B of which 209804 is used.

But when I use the "Optimize for debugging (-Og)" option, I run out of flash:

The nrf52833 has 512kB Flash memory; why do I only see 237056B as available? 

I would like to develop with the debugging options available. Could you please advise on how I can reduce the flash usage, particularly in the DFU configuration? I am using all the KConfigs that are enabled by CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU. Anytime I tried to remove one I got an error while testing DFU over BLE with the nRF Device Manager application. 

#Flag to indicate running on devkit for testing
CONFIG_RUNNING_ON_DEVKIT=y

CONFIG_BOARD_ENABLE_DCDC=n
CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y

# BLE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
## ADVERTISING NAME MUST BE CONFIGURED HERE
CONFIG_BT_DEVICE_NAME="DeviceNN"
CONFIG_BT_GATT_CLIENT=y
CONFIG_HEAP_MEM_POOL_SIZE=22528 
CONFIG_BT_RX_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=1024

# Application Event Manager
CONFIG_APP_EVENT_MANAGER=y

# Stack allocation for threads
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1024
CONFIG_STIMULUS_COMMAND_THREAD_STACK_SIZE=1024

# Custom config for app response timeout 
CONFIG_WRITE_RESPONSE_TIMEOUT_MS=5000

# Enable reboot
CONFIG_REBOOT=y

#Reset reason
CONFIG_NRFX_POWER=y

# Logging floating point values
CONFIG_FPU=y

# I2C 
CONFIG_SHELL=y
CONFIG_I2C=y

#Electrode Drivers
CONFIG_ADC=y
CONFIG_PWM=y

#Logging over RTT
CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_LOG=y

# Fuel Gauge npm1300
# CONFIG_NRF_FUEL_GAUGE=y
# CONFIG_REGULATOR=y
# CONFIG_SENSOR=y

CONFIG_THREAD_ANALYZER=y
CONFIG_THREAD_NAME=y
CONFIG_LOG_BUFFER_SIZE=4096

# FOTA
CONFIG_BOOTLOADER_MCUBOOT=y
#CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y
CONFIG_MCUMGR=y
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y
CONFIG_IMG_MANAGER=y
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH=y
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO=y
CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
# CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP=y

Parents
  • Hi,

    The nrf52833 has 512kB Flash memory; why do I only see 237056B as available? 

    This is because with BLE FOTA dual bank is mandatory.

    The reason is that the part of your firmware that handles BLE resides within the appliocation slot and if you don't have dual bank, i.e a slot where you can upload the image you're going to update with, you will with a single bank approach loose the BLE capability when you overwrite the application through the update which in turn leads to you not being able to receive anything.

    This is better explained here https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-8-bootloaders-and-dfu-fota/ and in quite a few other tickets on the forum (no worries if you didn't find them, but it's a common issue).

    What this means in practice is that BLE FOTA will only work on 512kB devices if your application is sufficiently small, and that you have a relatively small mcuboot. The peripheral_lbs sample showcases a minimal application through the minimal configuration, so you might see if there's something you can use there.

     CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU.

    This configuration basically enables everything w.r.t BLE DFU, so you can instead have a look at the smp server sample and the ble overlays and see if you're able to reduce the size there.

    https://github.com/nrfconnect/sdk-zephyr/tree/main/samples/subsys/mgmt/mcumgr/smp_svr

    You can also try to reduce the size of your mcuboot by adding LTO to the mcuboot build and disabling everything you don't need. Add the following to sysbuild/mcuboot/prj.conf (note that this is probably far too aggressive w.r.t removing features, so evaluate it yourself).

    sysbuild/mcuboot/prj.conf:
    #
    # Copyright (c) 2024 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
     
    CONFIG_PM=n
     
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"
     
    CONFIG_BOOT_SWAP_SAVE_ENCTLV=n
    CONFIG_BOOT_ENCRYPT_IMAGE=n
     
    CONFIG_BOOT_UPGRADE_ONLY=n
    CONFIG_BOOT_BOOTSTRAP=n
     
    ### mbedTLS has its own heap
    # CONFIG_HEAP_MEM_POOL_SIZE is not set
     
    ### We never want Zephyr's copy of tinycrypt.  If tinycrypt is needed,
    ### MCUboot has its own copy in tree.
    # CONFIG_TINYCRYPT is not set
    # CONFIG_TINYCRYPT_ECC_DSA is not set
    # CONFIG_TINYCRYPT_SHA256 is not set
     
    CONFIG_FLASH=y
    CONFIG_FPROTECT=y
    CONFIG_MCUBOOT_USE_ALL_AVAILABLE_RAM=y
    ### Various Zephyr boards enable features that we don't want.
    # CONFIG_BT is not set
    # CONFIG_BT_CTLR is not set
    # CONFIG_I2C is not set
     
    CONFIG_LOG=n
    CONFIG_LOG_MODE_MINIMAL=n # former CONFIG_MODE_MINIMAL
    ### Ensure Zephyr logging changes don't use more resources
    CONFIG_LOG_DEFAULT_LEVEL=0
    ### Use info log level by default
    CONFIG_MCUBOOT_LOG_LEVEL_INF=y
    ### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y
    CONFIG_CBPRINTF_NANO=y
    ### Use the minimal C library to reduce flash usage
    # Decrease memory footprint
    CONFIG_CBPRINTF_NANO=y
    CONFIG_TIMESLICING=n
    CONFIG_BOOT_BANNER=n
    CONFIG_CONSOLE=n
    CONFIG_CONSOLE_HANDLER=n
    CONFIG_UART_CONSOLE=n
    CONFIG_USE_SEGGER_RTT=n
    CONFIG_LOG=n
    CONFIG_ERRNO=n
    CONFIG_PRINTK=n
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_SPI=n
    CONFIG_SPI_NOR=n
    CONFIG_I2C=n
    CONFIG_UART_NRFX=n
     
    CONFIG_MCUBOOT_SERIAL=n
    CONFIG_BOOT_SERIAL_CDC_ACM=n
     
    # Enable LTO
    CONFIG_ISR_TABLES_LOCAL_DECLARATION=y
    CONFIG_LTO=y

    PS: I see that you might not be on NCS v2.7.0 or newer. Which version of NCS are you using?

    Kind regards,
    Andreas

  • Thank you for the detailed answer. I was using ncs 2.6.4. I now updated to 2.9.0 and followed instructions here to set up the FOTA over BLE with sysbuild, and created sysbuild/mcuboot/prf.conf with the contents you shared above.

    I still can't fit in the FLASH when I build with "Optimize for Debugging". So I will need to reduce the size of my application, or potentially look into switching to nrf52840 or using an external flash.

  • Hi,

    Glad to hear you were helped and you were able to migrate to 2.9.0.

    yali said:
    So I will need to reduce the size of my application, or potentially look into switching to nrf52840 or using an external flash.

    Yes, this is unfortunately the reality of dual bank DFU in NCS. I can get it to work for a 512kB device if I strip everything unnecessary, but then again I'm in practice reduced with a BLE application with very little features.

    We do typically recommend that you start developing with the largest development kit in the nRF family you aim to use. For the nRF52 family devices this means that you start with the nRF52840DK, or if you have already decided to use an external SPI NOR Flash device, then the nRF52833 or nRF52832. From here you implement everything you would need w.r.t peripherals, features, DFU etc and see how large your application is after optimizing it somewhat and sketching out a future DFU path where you have some room for new features if you need to add some. If you see that you can fit this on a smaller device, then you can relatively quickly remap the required peripherals and port your device to for instance the nrf52833 if you've started out with the nrf52840.

    Let me know if this makes sense for you, and feel free to ask follow up questions if you have anything unanswered w.r.t this topic

    Kind regards,
    Andreas

Reply
  • Hi,

    Glad to hear you were helped and you were able to migrate to 2.9.0.

    yali said:
    So I will need to reduce the size of my application, or potentially look into switching to nrf52840 or using an external flash.

    Yes, this is unfortunately the reality of dual bank DFU in NCS. I can get it to work for a 512kB device if I strip everything unnecessary, but then again I'm in practice reduced with a BLE application with very little features.

    We do typically recommend that you start developing with the largest development kit in the nRF family you aim to use. For the nRF52 family devices this means that you start with the nRF52840DK, or if you have already decided to use an external SPI NOR Flash device, then the nRF52833 or nRF52832. From here you implement everything you would need w.r.t peripherals, features, DFU etc and see how large your application is after optimizing it somewhat and sketching out a future DFU path where you have some room for new features if you need to add some. If you see that you can fit this on a smaller device, then you can relatively quickly remap the required peripherals and port your device to for instance the nrf52833 if you've started out with the nrf52840.

    Let me know if this makes sense for you, and feel free to ask follow up questions if you have anything unanswered w.r.t this topic

    Kind regards,
    Andreas

Children
No Data
Related