nRF9160dk FOTA using external flash, ncs 2.0.2

Hi, 

I am using nRf9160dk with mcuboot secondary image on external flash base on AZURE_FOTA example, ncs 2.0.2.

Found the bootloader cannot runs primary image.

So, I need advice on how to set up the mcuboot secondary with SPI flash.

*** Booting Zephyr OS build v3.0.99-ncs1-1  ***
I: Starting bootloader
W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=128 - too small?
E: Image in the primary slot is not valid!
E: Unable to find bootable image

Checked the partition with west build -t partition_manager_report .

+------------------------------------------+
| 0x0: external_flash (0x800000 - 8192kB)  |
| 0x0: mcuboot_secondary (0x70000 - 448kB) |
+------------------------------------------+

  flash_primary (0x100000 - 1024kB):
+--------------------------------------------------+
| 0x0: mcuboot (0xc000 - 48kB)                     |
| 0xc000: EMPTY_0 (0x4000 - 16kB)                  |
+---0x10000: mcuboot_primary (0xe8000 - 928kB)-----+
+---0x10000: tfm_secure (0xc200 - 48kB)------------+
| 0x10000: mcuboot_pad (0x200 - 512B)              |
+---0x10200: mcuboot_primary_app (0xe7e00 - 927kB)-+
| 0x10200: tfm (0xc000 - 48kB)                     |
+---0x1c200: tfm_nonsecure (0xdbe00 - 879kB)-------+
| 0x1c200: app (0xdbe00 - 879kB)                   |
+---0xf8000: nonsecure_storage (0x8000 - 32kB)-----+
| 0xf8000: settings_storage (0x2000 - 8kB)         |
| 0xfa000: littlefs_storage (0x6000 - 24kB)        |
+--------------------------------------------------+

  otp (0x2f4 - 756B):
+------------------------------+
| 0xff8108: otp (0x2f4 - 756B) |
+------------------------------+

  sram_primary (0x40000 - 256kB):
+--------------------------------------------------+
+---0x20000000: sram_secure (0x10000 - 64kB)-------+
| 0x20000000: tfm_sram (0x10000 - 64kB)            |
+---0x20010000: sram_nonsecure (0x30000 - 192kB)---+
+---0x20010000: nrf_modem_lib_sram (0x44e8 - 17kB)-+
| 0x20010000: nrf_modem_lib_ctrl (0x4e8 - 1kB)     |
| 0x200104e8: nrf_modem_lib_tx (0x2000 - 8kB)      |
| 0x200124e8: nrf_modem_lib_rx (0x2000 - 8kB)      |
+--------------------------------------------------+
| 0x200144e8: sram_primary (0x2bb18 - 174kB)       |
+--------------------------------------------------+

My configuration as follows:

child_image\mcuboot\boards\nrf9160dk_nrf9160_mcuboot.overlay

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

&spi3 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi3_default_alt>;
	pinctrl-1 = <&spi3_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
	mx25r64: mx25r6435f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <80000000>;
		label = "MX25R64";
		jedec-id = [c2 28 17];
		size = <67108864>;
	};
};

&pinctrl {
	spi3_default_alt: spi3_default_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 13)>,
				<NRF_PSEL(SPIM_MOSI, 0, 11)>,
				<NRF_PSEL(SPIM_MISO, 0, 12)>;
		};
	};

	spi3_sleep_alt: spi3_sleep_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 13)>,
				<NRF_PSEL(SPIM_MOSI, 0, 11)>,
				<NRF_PSEL(SPIM_MISO, 0, 12)>;
			low-power-enable;
		};
	};

};

child_image\mcuboot\prj_mcuboot.conf

CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096

CONFIG_MULTITHREADING=y

# MCUboot requires a large stack size, otherwise an MPU fault will occur
CONFIG_MAIN_STACK_SIZE=10240

CONFIG_DEBUG_OPTIMIZATIONS=y

# Enable flash operations
CONFIG_FLASH=y

# This must be increased to accommodate the bigger images.
CONFIG_BOOT_MAX_IMG_SECTORS=256

nrf9160dk_nrf9160_ns.overlay

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

&spi3 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi3_default_alt>;
	pinctrl-1 = <&spi3_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
	mx25r64: mx25r6435f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <80000000>;
		label = "MX25R64";
		jedec-id = [c2 28 17];
		size = <67108864>;
	};
};

&pinctrl {
	spi3_default_alt: spi3_default_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 13)>,
				<NRF_PSEL(SPIM_MOSI, 0, 11)>,
				<NRF_PSEL(SPIM_MISO, 0, 12)>;
		};
	};

	spi3_sleep_alt: spi3_sleep_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 13)>,
				<NRF_PSEL(SPIM_MOSI, 0, 11)>,
				<NRF_PSEL(SPIM_MISO, 0, 12)>;
			low-power-enable;
		};
	};

};

pm_static.yml

#include <autoconf.h>
#include <devicetree_legacy_unfixed.h>

external_flash:
  address: 0x0
  device: mx25r6435f
  region: external_flash
  size: 0x800000 
mcuboot_secondary:
  address: 0x0
  device: mx25r6435f
  region: external_flash
  size: 0x70000

prj.conf

#
# Copyright (c) 2020 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
# General config
CONFIG_REBOOT=y

# Log
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M=n
CONFIG_LTE_NETWORK_MODE_NBIOT=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n

# AT Host
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# MQTT
CONFIG_MQTT_KEEPALIVE=900

# Azure IoT Hub library
CONFIG_AZURE_IOT_HUB=y
CONFIG_AZURE_IOT_HUB_DEVICE_ID="nordic_960074368"
# Host name must be configured if DPS is not used
CONFIG_AZURE_IOT_HUB_HOSTNAME=""
# Change the security tag to the tag where relevant certificates are provisioned
CONFIG_AZURE_IOT_HUB_SEC_TAG=11
# Uncomment to get more verbose logging when debugging
# CONFIG_AZURE_IOT_HUB_LOG_LEVEL_DBG=y

# Uncomment and configure the options below to use DPS for device provisioning
CONFIG_AZURE_IOT_HUB_DPS=y
CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE="0ne0053A4FD"


# Azure FOTA
CONFIG_CJSON_LIB=y
CONFIG_AZURE_FOTA=y
CONFIG_AZURE_FOTA_APP_VERSION_AUTO=n
CONFIG_AZURE_FOTA_APP_VERSION="v0.0.1"
CONFIG_AZURE_FOTA_TLS=y
# Change the security tag to the tag where the certificates are provisioned
# for the server where the FOTA image is hosted
CONFIG_AZURE_FOTA_SEC_TAG=10
# Uncomment the below line to get more debug logging
# CONFIG_AZURE_FOTA_LOG_LEVEL_DBG=y

# Heap and stacks
CONFIG_HEAP_MEM_POOL_SIZE=6144
CONFIG_MAIN_STACK_SIZE=1536

# Settings, needed for Azure Device Provisioning Service
CONFIG_FLASH=y
CONFIG_FCB=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_FCB=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n

# Modem library
CONFIG_NRF_MODEM_LIB=y

# newlibc
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# FOTA Download
CONFIG_FOTA_DOWNLOAD=y
CONFIG_FOTA_DOWNLOAD_PROGRESS_EVT=y
CONFIG_AZURE_FOTA_FILE_PATH_MAX_LEN=200

# Download Client
CONFIG_DOWNLOAD_CLIENT=y
CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE_1024=y
CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096
CONFIG_DOWNLOAD_CLIENT_LOG_LEVEL_INF=y
CONFIG_DOWNLOAD_CLIENT_BUF_SIZE=2300

# DFU Target
CONFIG_DFU_TARGET=y

# Application update support
CONFIG_BOOTLOADER_MCUBOOT=y

# Image manager
CONFIG_IMG_MANAGER=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y

#################################################
# Config using external flash memory and littleFS.
#################################################
CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=32
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
# Need this when storage is on flash
# CONFIG_MPU_ALLOW_FLASH_WRITE=y

CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

  • Hi ,

    Thanks for your support and sorry for my late reply.

    I works properly with the example.

    By the way, my external flash needs to be portioned.

    I created a static partition for the external flash using the "pm static.yml" file.

    #include <autoconf.h>
    EMPTY_0:
      address: 0xc000
      end_address: 0x10000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0x4000
    EMPTY_1:
      address: 0xf0000
      end_address: 0xf8000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0x8000
    app:
      address: 0x1c200
      end_address: 0x80000
      region: flash_primary
      size: 0x63e00
    littlefs_storage:
      address: 0xfa000
      align:
        start: 0x8000
      end_address: 0xfb000
      inside:
      - nonsecure_storage
      placement:
        before:
        - end
      region: flash_primary
      size: 0x1000
    nvs_storage:
      address: 0xfb000
      align:
        start: 0xb000
      end_address: 0xfc000
      inside:
      - nonsecure_storage
      placement:
        before:
        - end
      region: flash_primary
      size: 0x1000
    reserved_storage:
      address: 0xfc000
      align:
        start: 0x8000
      end_address: 0x10000
      inside:
      - nonsecure_storage
      placement:
        before:
        - end
      region: flash_primary
      size: 0x4000    
    mcuboot:
      address: 0x0
      end_address: 0xc000
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xc000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10200
      placement:
        align:
          start: 0x8000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0x10000
      end_address: 0x80000
      orig_span: &id001
      - tfm
      - mcuboot_pad
      - app
      region: flash_primary
      sharers: 0x1
      size: 0x70000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x80000
      orig_span: &id002
      - app
      - tfm
      region: flash_primary
      size: 0x6fe00
      span: *id002
    # mcuboot_secondary:
    #   address: 0x80000
    #   end_address: 0xf0000
    #   placement:
    #     after:
    #     - mcuboot_primary
    #     align:
    #       start: 0x8000
    #   region: flash_primary
    #   share_size:
    #   - mcuboot_primary
    #   size: 0x70000
    nonsecure_storage:
      address: 0xf8000
      end_address: 0x100000
      orig_span: &id003
      - settings_storage
      region: flash_primary
      size: 0x8000
      span: *id003
    nrf_modem_lib_ctrl:
      address: 0x2000b000
      end_address: 0x2000b4e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - tfm_sram
        - start
      region: sram_primary
      size: 0x4e8
    nrf_modem_lib_rx:
      address: 0x2000d4e8
      end_address: 0x2000f4e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_tx
      region: sram_primary
      size: 0x2000
    nrf_modem_lib_sram:
      address: 0x2000b000
      end_address: 0x2000f4e8
      orig_span: &id004
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x44e8
      span: *id004
    nrf_modem_lib_tx:
      address: 0x2000b4e8
      end_address: 0x2000b4e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_ctrl
      region: sram_primary
      size: 0x2000
    otp:
      address: 0xff8108
      end_address: 0xff83fc
      region: otp
      size: 0x2f4
    settings_storage:
      address: 0xf8000
      end_address: 0xfa000
      inside:
      - nonsecure_storage
      placement:
        align:
          start: 0x8000
        before:
        - end
      region: flash_primary
      size: 0x2000
    sram_nonsecure:
      address: 0x2000b000
      end_address: 0x20040000
      orig_span: &id005
      - sram_primary
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x35000
      span: *id005
    sram_primary:
      address: 0x2000f4e8
      end_address: 0x20040000
      region: sram_primary
      size: 0x30b18
    sram_secure:
      address: 0x20000000
      end_address: 0x200B0000
      orig_span: &id006
      - tfm_sram
      region: sram_primary
      size: 0x0B000
      span: *id006
    tfm:
      address: 0x10200
      end_address: 0x1c200
      inside:
      - mcuboot_primary_app
      placement:
        before:
        - app
      region: flash_primary
      size: 0xc000
    tfm_nonsecure:
      address: 0x1c200
      end_address: 0x80000
      orig_span: &id007
      - app
      region: flash_primary
      size: 0x63e00
      span: *id007
    tfm_secure:
      address: 0x10000
      end_address: 0x1c200
      orig_span: &id008
      - mcuboot_pad
      - tfm
      region: flash_primary
      size: 0xc200
      span: *id008
    tfm_sram:
      address: 0x20000000
      end_address: 0x2000B000
      inside:
      - sram_secure
      placement:
        after:
        - start
      region: sram_primary
      size: 0x0B000
    external_flash:
      address: 0x0
      device: MX25R64
      end_address: 0x800000
      region: external_flash
      size: 0x800000
    mcuboot_secondary:
      address: 0x00
      region: external_flash
      size: 0xF0000
    lte_modem_fw:
      address: 0xF0000
      region: external_flash
      size: 0x4F000
    abc_fw:
      address: 0x13F000
      region: external_flash
      size: 0xF5000 
    def_fw:
      address: 0x234000
      region: external_flash
      size: 0xF5000   
    datalogger_storage:
      address: 0x329000
      region: external_flash
      size: 0x450000
     

    The system can download successfully, however after rebooting to the bootloader, it displays that it cannot upgrade.

    [00:07:47.032,867] <inf> download_client: Downloaded 209000/214490 bytes (97%)
    [00:07:48.711,853] <inf> download_client: Downloaded 210000/214490 bytes (97%)
    [00:07:50.662,628] <inf> download_client: Downloaded 211000/214490 bytes (98%)
    [00:07:52.616,790] <inf> download_client: Downloaded 212000/214490 bytes (98%)
    [00:07:54.151,000] <inf> download_client: Downloaded 213000/214490 bytes (99%)
    [00:07:55.528,106] <inf> download_client: Downloaded 214000/214490 bytes (99%)
    [00:07:57.320,892] <inf> download_client: Downloaded 214490/214490 bytes (100%)
    [00:07:57.338,562] <inf> download_client: Download complete
    [00:07:57.444,396] <inf> dfu_target_mcuboot: MCUBoot image-0 upgrade scheduled. Reset device to apply
    AZURE_IOT_HUB_EVT_FOTA_DONE
    The device will reboot in 5 seconds to apply update
    AZURE_IOT_HUB_EVT_TWIN_RESULT_SUCCESS, ID: 477&$version=23ersion=9
    *** Booting Zephyr OS build v3.1.99-ncs1-1  ***
    I: Starting bootloader
    W: Cannot upgrade: not a compatible amount of sectors
    I: Bootloader chainload address offset: 0x10000
    *** Booting Zephyr OS build v3.1.99-ncs1-1  ***
    Azure FOTA sample started
    This may take a while if a modem firmware update is pending
    [00:00:00.497,985] <inf> azure_fota: Current firmware version: v0.0.1Ext
    Connecting to LTE network
    DNS correctly set
    +CEREG: 2,"C008","024BB1A1",9
    LTE cell changed: Cell ID: 38515105, Tracking area: 49160
    +CSCON: 1
    RRC mode: Connected
    +CEREG: 1,"C008","024BB1A1",9,,,"11100000","00010010"
    Network registration status: Connected - home network
    AZUREPSM parameter update: TAU: 10800, Active time: -1
    _IOT_HUB_EVT_CONNECTING
    AZURE_IOT_HUB_EVT_CONNECTED
    AZURE_IOT_HUB_EVT_READY
    [00:00:15.965,881] <wrn> azure_fota: FOTA image was not applied, rolled back
    [00:00:15.976,013] <wrn> azure_fota: Update job (ID: 3) was already attempted, aborting
    AZURE_IOT_HUB_EVT_TWIN_RECEIVED
    AZURE_IOT_HUB_EVT_TWIN_RESULT_SUCCESS, ID: 159&$version=24
    +CSCON: 0
    RRC mode: Idle

    Can we do the FOTA utilizing the external flash static partition?

  • Hi,

    Rung said:
    I works properly with the example.

    Ok, good, so that means that you have implemented the formerly mentioned fix for ncs v2.1.0.

     

    Which image are you downloading?

    When updating, it is important that the original static partition is kept for all update-images as well, to ensure that mcuboot recognizes the image properly.

     

    Kind regards,

    Håkon

  • Hi,

    Which image are you downloading?

    Like with the "azure_fota" sample I tested, I used the "app_update.bin" file.

    However, the "Cannot upgrade: not a compatible amount of sectors" error, I have divided the external flash memory by add the "pm_static.yml" file.

    When updating, it is important that the original static partition is kept for all update-images as well, to ensure that mcuboot recognizes the image properly.

    What is the "original static partition is kept for all-images as well" means?

    Did you mean we cannot costume the external flash partition by using the static partition, pm_static.yml file.

    If so, could you provide me some advise on how to partition the external flash?

  • Hi,

     

    Rung said:

    What is the "original static partition is kept for all-images as well" means?

    Did you mean we cannot costume the external flash partition by using the static partition, pm_static.yml file.

    If so, could you provide me some advise on how to partition the external flash?

    In order to successfully update, your "app_update.bin" must be provided with the same pm_static.yml as your original project.

    This is to ensure that the image is setup with the same flash address offset as mcuboot was configured to.

    Did you add this to your configuration? 

    Håkon Alseth said:
    CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

    And also changed this line:

        DEVICE "DT_CHOSEN(nordic_pm_ext_flash)"

    In file:

    https://github.com/nrfconnect/sdk-nrf/blob/v2.1.2/cmake/partition_manager.cmake#L215

     

    Note that you should delete the build and regenerate the project.

     

    Kind regards,

    Håkon

  • Hi,

    I have already implemented every update suggested on the project.

    Note that you should delete the build and regenerate the project.

    Thanks for your notification of this, I can use pm_static.yml and do the FOTA (ncs 2.1.2) without an error by delete the build and regenerate the project.

Related