MCUBoot’s secondary image on external flash on nrf9160

I am using nrf9160 custom board with an external flash memory mx25l6433f. I first tested the external flash with the example 'sdk-zephyr/samples/drivers/spi_flash_at45' and for it to work was added an '.overlay'

 

&spi3 {
	status = "okay";
	sck-pin = <8>;
	mosi-pin = <11>;
	miso-pin = <10>;
	cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
	mx25l64: mx25l6433f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <8000000>;
		label = "MX25L64";
		jedec-id = [c2 20 17];
		sfdp-bfp = [
			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
		];
		size = <67108864>;
		has-dpd;
		t-enter-dpd = <10000>;
		t-exit-dpd = <35000>;
	};
};

and on my 'proj.conf' added

# Test ext Flash
CONFIG_SPI=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_SPI_NOR=y

Compiled and tested. The external flash is working.

After this i tried to implement 'MCUBOOT secondary on external flash', after reading several posts i ended with this configurations:

nrf9160dk_nrf9160_ns.overlay

&spi3 {
	status = "okay";
	sck-pin = <8>;
	mosi-pin = <11>;
	miso-pin = <10>;
	cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
	mx25l64: mx25l6433f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <8000000>;
		label = "MX25L64";
		jedec-id = [c2 20 17];
		sfdp-bfp = [
			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
		];
		size = <67108864>;
		has-dpd;
		t-enter-dpd = <10000>;
		t-exit-dpd = <35000>;
	};
};

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

prj.conf

# Test ext Flash
CONFIG_SPI=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_SPI_NOR=y

# set mcuboot_secondary on external flash
# This value must match the size of the MCUboot primary partition
CONFIG_PM_PARTITION_SIZE_MCUBOOT_SECONDARY=0xe0000

mcuboot.conf

# Enable flash operations
CONFIG_FLASH=y

# This value must match the size of the MCUboot primary partition.
CONFIG_PM_PARTITION_SIZE_MCUBOOT_SECONDARY=0xe0000

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

In the end, after applying the changes my flash space doubled the amount and on 'build\build_nrf9160dk_nrf9160_ns\partitions.yml' we can see the external flash and mcuboot secondary on external flash

...
external_flash:
  address: 0xe0000
  end_address: 0x800000
  region: external_flash
  size: 0x720000
mcuboot:
  address: 0x8200
  end_address: 0x10000
  placement:
    before:
    - mcuboot_primary
  region: flash_primary
  sharers: 0x1
  size: 0x7e00
mcuboot_pad:
  address: 0x18000
  end_address: 0x18200
  placement:
    align:
      start: 0x8000
    before:
    - mcuboot_primary_app
  region: flash_primary
  sharers: 0x2
  size: 0x200
mcuboot_primary:
  address: 0x18000
  end_address: 0xf8000
  orig_span: &id002
  - mcuboot_pad
  - app
  - spm
  region: flash_primary
  size: 0xe0000
  span: *id002
mcuboot_primary_app:
  address: 0x18200
  end_address: 0xf8000
  orig_span: &id003
  - app
  - spm
  region: flash_primary
  size: 0xdfe00
  span: *id003
mcuboot_secondary:
  address: 0x0
  device: MX25L64
  end_address: 0xe0000
  placement:
    align:
      start: 0x4
  region: external_flash
  size: 0xe0000
...

Then i programmed it to nrf9160 and it doesn't boot.

In one of the attempts to put it to work i removed the line 'CONFIG_PM_PARTITION_SIZE_MCUBOOT_SECONDARY=0xe0000' from mcuboot.conf and programmed it to nrf9160, this time it booted and started the program, but when i tried to update the firmware through DFU it says there is not enough space to store the update

Is this a bug, or did I simply went off track somewhere? Thanks.

  • In nRF9160: HTTP application update using the nRF9160DK's external flash, I have modified the http_update/application_update sample to support MCUboot updates using the 91DK's onboard external flash as secondary slot. I tested this sample with NCS v1.7.0, but I guess it will work fine with NCS v1.8.0 as well.

    Test it yourself by following the steps under Testing

    In this sample I have set the secondary partitions through the prj.conf file, but it's probably better practice to use a pm_static.yml file, e.g. like done in this sample: Serial DFU using external flash.

    Best regards,

    Simon

  • Hi Simon,

    Thks for your help.

    I went through the file from your sample and tried to replicate the configurations to mine, but with no success. So before coming here i downloaded your example and created a project on segger, then when i try to build the solution it gives an error

    In order to create the project i had to add to 'nrf9160dk_nrf9160_ns.overlay' &SPI3

    &spi3 {
    	status = "okay";
    	sck-pin = <8>;
    	mosi-pin = <11>;
    	miso-pin = <10>;
    	cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
    	mx25r64: mx25r6435f@0 {
    		compatible = "jedec,spi-nor";
    		reg = <0>;
    		spi-max-frequency = <8000000>;
    		label = "MX25R64";
    		jedec-id = [c2 28 17];
    		sfdp-bfp = [
    			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
    			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
    			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
    			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
    		];
    		size = <67108864>;
    		has-dpd;
    		t-enter-dpd = <10000>;
    		t-exit-dpd = <35000>;
    	};
    };
    
    / {
    	chosen {
    		nordic,pm-ext-flash = &mx25r64;
    	};
    };

    Can you help to diagnose the issue?

  • I found the error.

    In my case as i'm using an custom board, the definition of SPI3 was on '*.overlay' and mcuboot doesn't have access to it. To solve it add this line to 'CMakeLists.txt' right after cmake_minimum_required(...)

    cmake_minimum_required(VERSION ......)
    
    set(mcuboot_DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${BOARD}.overlay")

    This way mcuboot knows jedec-id and size and compiles without a problem

  • That makes sense. I'm happy you found the solution. You could also add the external flash to the custom board dts files.

  • Hi Simon and ICM_UC,

    Just a heads up - it doesn't look like this example is properly putting the secondary partition into external flash.  I built it and took a look at build/partitions.yml - check out mcuboot_secondary:

    mcuboot_secondary:
      address: 0x88000
      end_address: 0x100000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x78000
    

    Also, when you build the sample, you can see that only about half of the Nordic flash is available for the application (~425K), instead of almost the entire flash (~900K):

    [218/223] Linking C executable zephyr/zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:      100572 B     425472 B     23.64%
                SRAM:       30112 B     178968 B     16.83%
            IDT_LIST:          0 GB         2 KB      0.00%
            

    The reason I was looking at this is because I recently got FOTA working on nRF91 using an external SPI flash for the secondary image, and it actually took a patch to MCUBoot to get it working:

    https://github.com/nrfconnect/sdk-mcuboot/pull/200

    I suspect if you fix the config for this sample to actually use the external SPI flash for mcuboot_secondary, you'll also need this patch as well for NCS v1.7.0.

Related