Perform FOTA to application built with SPM with application built with TFM

Dear All,

We are want to transition from SDK v1.6.0 to 2.1.0.

At the moment we have several devices that are were programmed with the SPM and now we want to be able to do FOTA on them to version 2.1.0 with the application using TFM.

Preliminary tests are not showing promising results, as the device simply reverts back to the original firmware that was on the device.

Is there perhaps an intermediate step that would be advised?

  •  

    The partions.yml of the orignal project is this:

    EMPTY_0:
      address: 0xc000
      end_address: 0x10000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0x4000
    EMPTY_1:
      address: 0xf0000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0xa000
    app:
      address: 0x20200
      end_address: 0x80000
      region: flash_primary
      size: 0x5fe00
    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
      - spm
      - app
      - mcuboot_pad
      region: flash_primary
      sharers: 0x1
      size: 0x70000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x80000
      orig_span: &id002
      - app
      - spm
      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
    nrf_modem_lib_ctrl:
      address: 0x20010000
      end_address: 0x200104e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - spm_sram
        - start
      region: sram_primary
      size: 0x4e8
    nrf_modem_lib_rx:
      address: 0x200124e8
      end_address: 0x200144e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_tx
      region: sram_primary
      size: 0x2000
    nrf_modem_lib_sram:
      address: 0x20010000
      end_address: 0x200144e8
      orig_span: &id003
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x44e8
      span: *id003
    nrf_modem_lib_tx:
      address: 0x200104e8
      end_address: 0x200124e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_ctrl
      region: sram_primary
      size: 0x2000
    nvs_storage:
      address: 0xfa000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x6000
    otp:
      address: 0xff8108
      end_address: 0xff83fc
      region: otp
      size: 0x2f4
    spm:
      address: 0x10200
      end_address: 0x20200
      inside:
      - mcuboot_primary_app
      placement:
        before:
        - app
      region: flash_primary
      size: 0x10000
    spm_sram:
      address: 0x20000000
      end_address: 0x20010000
      inside:
      - sram_secure
      placement:
        after:
        - start
      region: sram_primary
      size: 0x10000
    sram_nonsecure:
      address: 0x20010000
      end_address: 0x20040000
      orig_span: &id004
      - sram_primary
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x30000
      span: *id004
    sram_primary:
      address: 0x200144e8
      end_address: 0x20040000
      region: sram_primary
      size: 0x2bb18
    sram_secure:
      address: 0x20000000
      end_address: 0x20010000
      orig_span: &id005
      - spm_sram
      region: sram_primary
      size: 0x10000
      span: *id005
    


    And from the new project is this:

    EMPTY_0:
      address: 0x14200
      end_address: 0x18000
      placement:
        before:
        - s1_pad
      region: flash_primary
      size: 0x3e00
    EMPTY_1:
      address: 0x24200
      end_address: 0x28000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0x3e00
    EMPTY_2:
      address: 0xfe000
      end_address: 0x100000
      placement:
        after:
        - nvs_storage
      region: flash_primary
      size: 0x2000
    app:
      address: 0x30200
      end_address: 0x90000
      region: flash_primary
      size: 0x5fe00
    app_image:
      address: 0x28200
      end_address: 0x90000
      orig_span: &id001
      - tfm
      - app
      region: flash_primary
      size: 0x67e00
      span: *id001
    b0:
      address: 0x0
      end_address: 0x8000
      placement:
        after:
        - start
      region: flash_primary
      size: 0x8000
    b0_container:
      address: 0x0
      end_address: 0x8000
      orig_span: &id002
      - b0
      region: flash_primary
      size: 0x8000
      span: *id002
    mcuboot:
      address: 0x8200
      end_address: 0x14200
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      sharers: 0x1
      size: 0xc000
    mcuboot_pad:
      address: 0x28000
      end_address: 0x28200
      placement:
        align:
          start: 0x8000
        before:
        - mcuboot_primary_app
      region: flash_primary
      sharers: 0x2
      size: 0x200
    mcuboot_primary:
      address: 0x28000
      end_address: 0x90000
      orig_span: &id003
      - mcuboot_pad
      - app
      - tfm
      region: flash_primary
      sharers: 0x1
      size: 0x68000
      span: *id003
    mcuboot_primary_app:
      address: 0x28200
      end_address: 0x90000
      orig_span: &id004
      - app
      - tfm
      region: flash_primary
      size: 0x67e00
      span: *id004
    mcuboot_secondary:
      address: 0x90000
      end_address: 0xf8000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x68000
    nonsecure_storage:
      address: 0xf8000
      end_address: 0xfe000
      orig_span: &id005
      - nvs_storage
      region: flash_primary
      size: 0x6000
      span: *id005
    nrf_modem_lib_ctrl:
      address: 0x20008000
      end_address: 0x200084e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - tfm_sram
        - start
      region: sram_primary
      size: 0x4e8
    nrf_modem_lib_rx:
      address: 0x2000a4e8
      end_address: 0x2000c4e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_tx
      region: sram_primary
      size: 0x2000
    nrf_modem_lib_sram:
      address: 0x20008000
      end_address: 0x2000c4e8
      orig_span: &id006
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x44e8
      span: *id006
    nrf_modem_lib_tx:
      address: 0x200084e8
      end_address: 0x2000a4e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_ctrl
      region: sram_primary
      size: 0x2000
    nvs_storage:
      address: 0xf8000
      align:
        start: 0x8000
      end_address: 0xfe000
      inside:
      - nonsecure_storage
      placement:
        align:
          start: 0x8000
        before:
        - end
      region: flash_primary
      size: 0x6000
    otp:
      address: 0xff8388
      end_address: 0xff83fc
      region: otp
      size: 0x74
    provision:
      address: 0xff8108
      end_address: 0xff8388
      region: otp
      size: 0x280
    s0:
      address: 0x8000
      end_address: 0x14200
      orig_span: &id007
      - mcuboot
      - s0_pad
      region: flash_primary
      size: 0xc200
      span: *id007
    s0_image:
      address: 0x8200
      end_address: 0x14200
      orig_span: &id008
      - mcuboot
      region: flash_primary
      size: 0xc000
      span: *id008
    s0_pad:
      address: 0x8000
      end_address: 0x8200
      placement:
        after:
        - b0_container
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    s1:
      address: 0x18000
      end_address: 0x24200
      orig_span: &id009
      - s1_pad
      - s1_image
      region: flash_primary
      size: 0xc200
      span: *id009
    s1_image:
      address: 0x18200
      end_address: 0x24200
      placement:
        after:
        - s1_pad
        - s0
      region: flash_primary
      share_size:
      - mcuboot
      size: 0xc000
    s1_pad:
      address: 0x18000
      end_address: 0x18200
      placement:
        after:
        - s0
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    sram_nonsecure:
      address: 0x20008000
      end_address: 0x20040000
      orig_span: &id010
      - sram_primary
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x38000
      span: *id010
    sram_primary:
      address: 0x2000c4e8
      end_address: 0x20040000
      region: sram_primary
      size: 0x33b18
    sram_secure:
      address: 0x20000000
      end_address: 0x20008000
      orig_span: &id011
      - tfm_sram
      region: sram_primary
      size: 0x8000
      span: *id011
    tfm:
      address: 0x28200
      end_address: 0x30200
      inside:
      - mcuboot_primary_app
      placement:
        before:
        - app
      region: flash_primary
      size: 0x8000
    tfm_nonsecure:
      address: 0x30200
      end_address: 0x90000
      orig_span: &id012
      - app
      region: flash_primary
      size: 0x5fe00
      span: *id012
    tfm_secure:
      address: 0x28000
      end_address: 0x30200
      orig_span: &id013
      - mcuboot_pad
      - tfm
      region: flash_primary
      size: 0x8200
      span: *id013
    tfm_sram:
      address: 0x20000000
      end_address: 0x20008000
      inside:
      - sram_secure
      placement:
        after:
        - start
      region: sram_primary
      size: 0x8000
    

  • From these files, I can see that both the slot size and start addresses (mcuboot_primary) of the projects are not the same.

    These addresses are statically defined by the partition manager at build, and as far as I know MCUboot has no way of knowing how to update these.
    From Image slots:

    "Normally, the bootloader will only run an image from the primary slot, so images must be built such that they can run from that fixed location in flash"

    So to be able to update your application, make sure that the mcuboot image slots are in the same location and size in both projects.

    You can do this using pm_static.yml. See applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/pm_static.yml for an example.

    Regards,
    Sigurd Hellesvik

  • I am not sure how to do this in the present setup as the newer version has many more partitions compared to the old one.

    Effectively I am not sure what should I put into thepm_static.yaml. Could you maybe provide an explanation of what are the important parts based on the yaml files I provided?

    Thanks a lot for the assistance so far

  • Hi,

    NSIB

    One thing I just now caught:

    You are trying to add an immutable first stage bootloader (NSIB aka b0) in your new project.
    This will be hard to impossible to do using Device Firmware Update (DFU).
    The first bootloader that runs on your device is immutable, meaning that you can not change it, for security reasons.
    Therefore, you can not switch Immutable First Stage MCUboot for a First Stage Nordic Secure Immutable Bootloader (NSIB).

    So I guess this is the main reason why your DFU fails here.

    Before using pm_static.yml, disable NSIB and try to do DFU again, with only one bootloader.

    PM_STATIC.YML

    As long as the mcuboot slots are in the same places and of the same size, I think your application should be able to boot just fine.
    Keep in mind that if you have non-volatile data in a partition, and change the addresses of this partition, you may loose this non-volatile data after DFU.

    To create pm_static, I would start by doing the following:

    1. Open sample_pm_static.yml
    2. Open your old build/partitions.yml
    3. Observe that content in autogenerated file is similar to pm_static file from the two files above.
    4. Open <your_project>/pm_static.yml
    5. Copy app and mcuboot content from partitions.yml to pm_static.yml
    6. Compare with sample_pm_static.yml and remove all parts of yml that is not needed (such as end_address)
    7. Try to build project.

    Regards,
    Sigurd Hellesvik

  •  

    Indeed the issue was the NSIB. I was including it in my project while trying to replicate the sample in the SDK but it is not needed in my case. Thank you very much for your detailed explanation and assistance

Related