PM_Static with MCU_Boot and external Flash

Hello and thanks for reading. I am working with the NRF5340DK and Zephyr (SDK 2.5.0).

As our project has grown, we can no longer fit all our code and MCU boot in the internal flash. Seeing as the DK has an external flash chip on QSPI, we figured we would use that to store our code.

We started out with the example provided in the developer academy, and that worked well.

It seemed wasteful, however, to have 8K of flash and to only use ~1K, keeping the second MCUBOOT image on the NRF5340's internal flash.

Also, our code has kept growing, so we decided to try and put both the primary and secondary slots for MCUBOOT on the external flash, with two images of 4K each.

This is leading to problems with setting up our PM_Static.yml, and I was hopeful you could take a look and help us figure out what we are doing wrong.

Here is my PM_Static.yml right now:

# Custom NVS storage partition (flash_primary)
custom_nvs_storage:
  address: 0x00000
  size: 0x2000  # 8 KB
  region: flash_primary

# Settings storage partition (flash_primary)
settings_storage:
  address: 0x2000
  size: 0x2000  # 8 KB
  region: flash_primary

# External QSPI Flash (8 MB)
qspi_flash:
  address: 0x0
  region: external_flash
  size: 0x800000  # 8 MB

# mcuboot partitions in QSPI flash (external flash)
mcuboot_primary:
  address: 0x0
  size: 0x400000  # 4 MB
  region: qspi_flash

mcuboot_secondary:
  address: 0x400000
  size: 0x400000  # 4 MB
  region: qspi_flash

And here are the relevant error messages:

-- Found partition manager static configuration: C:/Users/foo/Documents/GitHub/foo/pm_static.yml
Partition 'settings_storage' is not included in the dynamic resolving since it is statically defined.
Partition 'mcuboot_primary' is not included in the dynamic resolving since it is statically defined.
Partition 'mcuboot_secondary' is not included in the dynamic resolving since it is statically defined.
Partition manager failed: End of last partition is after last valid address
Failed to partition region flash_primary, size of region: 1048576
Partition Configuration:
custom_nvs_storage:
  size: 8192
mcuboot:
  placement: {}
  size: 49152
mcuboot_pad:
  placement:
    before:
    - mcuboot_primary_app
  size: 512
settings_storage:
  size: 8192

And here are the project configs in case that helps you:

MCUBoot project config:

CONFIG_FLASH=y

CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
# CONFIG_BOOT_SIGNATURE_KEY_FILE="dev_ec256_priv.pem"
CONFIG_MAIN_STACK_SIZE=10240
CONFIG_MULTITHREADING=y

CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y

CONFIG_BOOT_ENCRYPT_IMAGE=y
# CONFIG_BOOT_ENCRYPTION_KEY_FILE="dev_ec256_priv.pem"

#clock config
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y

CONFIG_SOC_HFXO_CAP_EXTERNAL=n
CONFIG_SOC_HFXO_CAP_INTERNAL=y
CONFIG_SOC_HFXO_CAP_INT_VALUE_X2=16

#Code protection
CONFIG_NRF_APPROTECT_LOCK=y

CONFIG_NORDIC_QSPI_NOR=y
CONFIG_BOOT_MAX_IMG_SECTORS=512

mcuboot overlay:

/ {
	chosen {
		nordic,pm-ext-flash = &mx25r64;
	};
};

prj.conf

#GPIO
CONFIG_GPIO=y
CONFIG_PINCTRL=y

#UART & SERIAL & system
CONFIG_SERIAL=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

CONFIG_MAIN_STACK_SIZE=8192
CONFIG_LOG=y
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192

CONFIG_TIMESLICING=y

#CPP
CONFIG_CPP=y
CONFIG_REQUIRES_FULL_LIBCPP=y
CONFIG_STD_CPP20=y

#i2C
CONFIG_I2C=y

#spi
CONFIG_SPI=y

#usb
CONFIG_USB_DEVICE_VID=0xC0FF
CONFIG_USB_DEVICE_PID=0xA55A


#flash
CONFIG_SETTINGS=y
CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_NVS=y
CONFIG_FLASH_MAP=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_FILE_SYSTEM=y
CONFIG_SOC_FLASH_NRF=y
CONFIG_NORDIC_QSPI_NOR=y

#PM
CONFIG_PARTITION_MANAGER_ENABLED=y

#math
CONFIG_CMSIS_DSP=y
CONFIG_CMSIS_DSP_SVM=y
CONFIG_NEWLIB_LIBC=y
CONFIG_FPU=y
# CONFIG_CMSIS_DSP_TRANSFORM=y
# CONFIG_TFM_ENABLE_CP10CP11=y
CONFIG_CMSIS_DSP_FILTERING=y

#BLE
CONFIG_BT=y
CONFIG_BT_BONDABLE=n #dont need bonding for HID, get rid of it.
CONFIG_BT_SETTINGS=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_BROADCASTER=y
CONFIG_BT_OBSERVER=y

CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_DEVICE_NAME_MAX=30

#NUS
CONFIG_BT_NUS=y
CONFIG_BT_NUS_AUTHEN=n

#BT BATTERY SERVICE (BAS)
CONFIG_BT_BAS=y

#DIS
CONFIG_BT_DIS=y #all non-pnp DIS settings are done dynamically
CONFIG_BT_DIS_PNP=n
CONFIG_SETTINGS_RUNTIME=y
CONFIG_BT_DIS_SETTINGS=y

CONFIG_BT_DIS_MODEL="foo"
CONFIG_BT_DIS_MANUF="foo"
CONFIG_BT_DIS_SERIAL_NUMBER=y
CONFIG_BT_DIS_FW_REV=y
CONFIG_BT_DIS_HW_REV=y
CONFIG_BT_DIS_SW_REV=y
CONFIG_BT_DIS_SERIAL_NUMBER_STR="xxxxxxxx"
CONFIG_BT_DIS_FW_REV_STR="0"
CONFIG_BT_DIS_HW_REV_STR="0"
CONFIG_BT_DIS_SW_REV_STR="0"

#BT HID
CONFIG_NCS_SAMPLES_DEFAULTS=y

CONFIG_BT_MAX_CONN=6
CONFIG_BT_SMP=y
CONFIG_BT_L2CAP_TX_BUF_COUNT=5
CONFIG_BT_DEVICE_APPEARANCE=962

CONFIG_BT_HIDS=y
CONFIG_BT_HIDS_MAX_CLIENT_COUNT=2
CONFIG_BT_HIDS_DEFAULT_PERM_RW_ENCRYPT=y
CONFIG_BT_GATT_UUID16_POOL_SIZE=40
CONFIG_BT_GATT_CHRC_POOL_SIZE=20

CONFIG_BT_CONN_CTX=y

#2MEG PHY & MTU
CONFIG_BT_AUTO_PHY_UPDATE=n
# CONFIG_BT_CTLR_PHY_2M=y
# CONFIG_BT_AUTO_PHY_UPDATE=y
# CONFIG_BT_USER_PHY_UPDATE=y

CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_L2CAP_TX_MTU=247

CONFIG_BT_ATT_PREPARE_COUNT=4
CONFIG_BT_CONN_TX_MAX=10
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y


CONFIG_BT_PERIPHERAL_PREF_MIN_INT=6
CONFIG_BT_PERIPHERAL_PREF_MAX_INT=24
CONFIG_BT_PERIPHERAL_PREF_LATENCY=0
CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=400

#ADC
CONFIG_ADC=y
CONFIG_ADC_ASYNC=y

#timer
CONFIG_COUNTER=y

CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y 
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y 
CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y 
CONFIG_SOC_HFXO_CAP_EXTERNAL=n 
CONFIG_SOC_HFXO_CAP_INTERNAL=y 
CONFIG_SOC_HFXO_CAP_INT_VALUE_X2=16 
CONFIG_BOOTLOADER_MCUBOOT=y 
CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y 
CONFIG_BT_MAX_PAIRED=1 
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y 

  • Hello, thanks again for your help!

    We are making progress, but now we have a new issue, in that region "RAM" is now overflowing... Im a little confused about what might be causing this, as my understanding is that we have not made any changes to what goes in ram? Does this mean my code is too large for the the sizes of the partitions in the example PM_Static.yml file?

    c:/ncs/toolchains/ce3b5ff664/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: zephyr\zephyr_pre0.elf section `bss' will not fit in region `RAM'
    c:/ncs/toolchains/ce3b5ff664/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: region `RAM' overflowed by 273688 bytes

    Thanks for all your help

  • Hello,

    I assume this linker error is raised when building MCUBoot since you got this after enabling the netcore update functionality. The RAM partition which holds the emulated flash partition (mcuboot_primary_1) is 256K.

    Is the application built for the non-secure processing environment (i.e. are you building for cpuapp/ns) by any chance? In that case, please ensure the  CONFIG_MCUBOOT_USE_ALL_AVAILABLE_RAM symbol is selected in the MCUBoot build (build/mcuboot/zephyr/.config). 

    I have also started working on an example to try this out myself. I'm including it here if you want to compare the configurations:

    1016.peripheral_lbs_dfu_w_xip_test.zip

    Best regards,

    Vidar

  • Thanks for all of your help, I think we are almost there. I switched to the secure instead of ns, and that seems to have resolved the final error I was getting and it now builds. Is there anything else I should be aware of for having made this change?

    Looking at my output, I notice that my EXTFLASH is actually quite small:

    [590/608] Linking CXX executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used

            EXTFLASH:         360 B     261632 B      0.14%

               FLASH:      712056 B     916992 B     77.65%

                 RAM:      124488 B       440 KB     27.63%

            IDT_LIST:          0 GB        32 KB      0.00%

    Looking at the memory report, it seems the problem is just that the partitions need to be made bigger in pm_static.yml.

    Do I just need to make mcuboot_primary_2 and mcuboot_secondary_2 larger?

    Lastly, I tried downloading the code to my 5340DK and are getting no signs of life. No output in console, no LEDs and not detectable on NRF Connect app. Do you have any suggestions where I should start looking for debugging this?

    Thanks!

  • Thanks for the update. For ns builds, the bootloader will only have the access to the secure RAM by default, so this explains the linker error.

    i_4556 said:
    Do I just need to make mcuboot_primary_2 and mcuboot_secondary_2 larger?

    In addition to that, you will need to update the linker script which defines the EXTFLASH section to reflect the new partition size.

    i_4556 said:
    Lastly, I tried downloading the code to my 5340DK and are getting no signs of life. No output in console, no LEDs and not detectable on NRF Connect app. Do you have any suggestions where I should start looking for debugging this?

    To help narrow down the problem, could you please try running the sample I uploaded to your DK and see if you get the same result?

Related