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

  • 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

Related