MCUBoot runtime error: "Cannot upgrade: not a compatible amount of sectors" with external flash on nrf9160

Hi,

I am using NCS 2.1.2 with the [email protected] (but I have tested with 2.2.0-rc1 and it doesn't change anything). I have attached a simple example which should just place the MCUBoot secondary partition in the external flash with pm_static.yml. I am using the firmware here: https://github.com/simon-iversen/sdk-nrf/tree/d1a11f2c39e3b8fb0af7652e7e720626f0e1298e/samples/nrf9160/http_update/application_update to connect the NOR flash to the nrf91.

This appears to compile fine, but, on bootup I get the following errors printed by the bootloader:

W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=256 - too small?
W: Cannot upgrade: not a compatible amount of sectors

On stepping through the code, it appears that the flash_area_get_sectors function is returning -22 (EINVAL) for the secondary partition on the external flash because flash_area_open is failing with -19 (ENODEV). However, I know that the flash is working fine because (in the second example attached) littlefs on the external flash formats and mounts correctly.

I found in another thread this fix for a similar problem: https://github.com/nrfconnect/sdk-nrf/pull/9169/files# (I unfortunately cannot find the thread again) but I have applied this patch and it does not seem to change anything.

Could you please help me understand what the problem is here?

Thanks,

Jeremy

8156.nrf9160dk_extflash_mcuboot.zip

Parents
  • Hi Jeremy,

    Seems like you are not the first with this issue.

    Have a look at  RE: nRF9160dk FOTA using external flash, ncs 2.0.2 and see if that looks similar.
    Also apply the patch near the end of the case and see if that fixes your issue.

    Regards,
    Sigurd Hellesvik

  • File attached below:

    6076.nrf9160dk_extflash_mcuboot_littlefs.zip

    The DT_CHOSEN line from that patch is already present in 2.2.0-rc1 and the build already has the PM_OVERRIDE config - that one took me many days of time to find on its own ;)

    This is the output from 2.2.0-rc1:

    *** Booting Zephyr OS build v3.2.99-ncs1-rc1 ***
    I: Starting bootloader
    W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=256 - too small?
    W: Cannot upgrade: not a compatible amount of sectors
    I: Bootloader chainload address offset: 0x10000

    Thanks,

    Jeremy

  • Also I noticed that the pm_static.yml doesn't have the same size for the mcuboot_primary and mcuboot_secondary partitions. I guess the "share_size" directive is either being ignored or doesn't do what I expect it to do, and I can't find any documentation on it (I just took it from the autogenerated partitions.yml).

    I have attached a fixed version of the test project for reference, the only change is the partition size in pm_static.yml

    nrf9160dk_extflash_updated.zip

    Thanks,

    Jeremy

  • One other thing I forgot to add: I deleted the pm_static.yml file and added to prj.conf:

    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

    But still see the same output. The secondary partition is definitely being put in the external flash though with the fix you linked to:

    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: 0x100000
      orig_span: &id001
      - mcuboot_pad
      - app
      - tfm
      region: flash_primary
      size: 0xf0000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x100000
      orig_span: &id002
      - app
      - tfm
      region: flash_primary
      size: 0xefe00
      span: *id002
    mcuboot_secondary:
      address: 0x0
      device: DT_CHOSEN(nordic_pm_ext_flash)
      end_address: 0xf0000
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0xf0000

  • Hi Jeremy,

    I suspect that I know what your error is.

    You need to have a child_image/mcuboot/boards/nrf9160dk_nrf9160.overlay file to set the devicetree for the external flash in mcuboot as well.

    It has to be nrf9160dk_nrf9160.overlay  and not nrf9160dk_nrf9160_ns.overlay because mcuboot runs in the secure world.

    To test this, I created  project which enables mcuboot with external flash for the nRF9160DK.
    The configurations of this project is a bit messy, but I did not want to delete any which I commented out.
    This is because I got all the configurations here from Marshall in this answer.

    Board: [email protected]
    nRF Connect SDK: v2.2.0-rc1
    Enable external flash for the nRF9160: Simons sample
    Project:nrf9160_external_flash_mcuboot.zip

    Does this work for you?

    Regards,
    Sigurd Hellesvik

Reply Children
  • Hi Sigurd,

    Thanks! I have it working now. It seems that there were a few issues here:

    1. The DT_CHOSEN issue that is fixed in 2.2.0-rc1

    2. For the mcuboot build, it doesn't search for board overlays in the "boards" directory, only in "child_image/boards". I did have a secure overlay in the boards dir, but it didn't pick that up.

    3. If you don't have the *exact* same size partition for mcuboot_primary and mcuboot_secondary partitions (even if the secondary is much bigger than necessary) then mcuboot gives the error "W: Cannot upgrade: not a compatible amount of sectors". So if you define mcuboot_secondary in the pm_static.yml file, you must also define mcuboot_primary otherwise the PM could change the partition size without you knowing.

    It seems point 1 is already fixed. For point 2, can I suggest adding something to the documentation about this? For point 3, even though it is incorrect to have different partition sizes, I do think it is a bug that compilation is successful, seeing as it can never work anyway, and this problem can be checked at compile time. What does the "share_size" directive in pm_static.yml do if not require them to be the same? Like this:

    mcuboot_secondary:
      address: 0x0
      device: MX25R64
      end_address: 0x100000
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0x100000

    except that "share_size" doesn't appear to actually do anything.

    I really appreciate your help on this!

    Thanks,

    Jeremy

Related