OTA on external flash fails after having loaded an image

Hello,

I'm, trying to configure an nrf5340 based board to use the secondary boot image on an external SPI Flash.

The flash has tree partitions:

  • 0: The second boot space.
  • 1: The storage partition.
  • 2: A littlefs partition.

The partition has been defined in the overlay configuration file in the following way:

&w25q256jveiq0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;
		slot1_partition: partition@0 {
			label = "image-1";
            reg = <0x00000000 0x000f0000>;
        };
		
		storage_partition: partition@f0000 {
			label = "storage";
            reg = <0x000f0000 0x00002000>;
        };

		lfs1_part: partition@f2000 {
			label = "littlefs_storage";
			reg =  <0x000f2000 0x00F0E000>;
		};
	};
};

The portion of configuration regarding the external flash is the following:

# External partitions
CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
CONFIG_PM_PARTITION_REGION_SETTINGS_STORAGE_EXTERNAL=y
CONFIG_PM_PARTITION_REGION_NVS_STORAGE_EXTERNAL=y
CONFIG_PM_PARTITION_SIZE_LITTLEFS=0xF0E000

# Prevent the QSPI NOR driver to be automatically included by partition manager
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

At the first boot, typing "mcuboot" on the shell, the reported informations are the following:

rtt:~$ mcuboot

swap type: none
confirmed: 0

primary area (3):
  version: 2.0.0+0
  image size: 353164
  magic: unset
  swap type: none
  copy done: unset
  image ok: unset

failed to read secondary area (1) header: -5

The error happens because the flash partition is erased, and its content is all 0xFF.

Using the Android "Device Manager" App, the secondary image can be loaded without problems.

After the load has complete (test only), the "mcuboot" shell command shows the following:

rtt:~$ mcuboot

swap type: test
confirmed: 0

primary area (3):
  version: 2.0.0+0
  image size: 353164
  magic: unset
  swap type: none
  copy done: unset
  image ok: unset

secondary area (1):
  version: 2.0.1+0
  image size: 353164
  magic: good
  swap type: test
  copy done: unset
  image ok: unset

At this point, using the "Advanced" option in the Device Manager App, after performing a read operation, only the "Confirm" and "Erase" commands are available (the "Test" is grayed).

Pressing the "Confirm" command, nothing happens.

The same situation happens when issuing the "mcuboot confirm" command in the shell.

Following the function in the mcuboot_shell.c module with the gdb debugger, I notice that the boot_write_img_confirmed function is called.

This function calls the boot_set_confirmed function, that is commented in this way: "Marks the image with index 0 in the primary slot as confirmed."

In fact, the function calls the boot_set_confirmed_multi(0) sub-function.

At this point I'm confused: I need to confirm the image-1, not the primary image. How can I confirm the loaded image in the external flash? When using the OTA functions without the external flash, all works fine.

The Device Manager cannot perform any other operation, the only way to go back to a loadable situation is to perform an erase operation using the shell, with the command "mcuboot erase 1".

The erase function in the Device Manager do not works, it reports: "Bad state (6)".

After a successful erase operation performed with the shell, a load attempt with "test and confirm" results in the error "Image not confirmed".

Is there something wrong or missing in my configuration?

Thank you very much.

  • Hi Amanda, thanks for your reply and assistance.

    Both overlay and config for the mcuboot are similar to the examples you indicated to me.

    As I previously reported, my problem is that the CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 seems to be ignored by the cmake system, as the final autoconf.h contains a value of 65536.

    There is another strange behaviour for the mcuboot sub-project: In the first step, after the creation of the build directory, the cmake command is executed to populate the directory, in the following way:

     cmake -B . -DBOARD=nrf5340dk_nrf5340_cpuapp -G"Eclipse CDT4 - Ninja"  ../my_sorce_path/

    In the second step, the "ninja" command is launched to start the build.

    On the first build, the generated mcuboot/zephyr/zephyr.dts and mcuboot/zephyr/include/generetad/autoconf.h do not contain any of the configurations reported on the two files mcuboot.conf and mcuboot.overlay. It's necessary to modify the main prj.conf, for example by changing the version in the CONFIG_MCUBOOT_IMAGE_VERSION definition, and run ninja again. Only after this second step, the generated files in the mcuboot path reflect my settings, except the CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE which still presents a value of 64K instead of 4K.

    Is there something wrong in the cmake procedure I reported, or I'm missing something?

    Thank you very much.

  • Hi,

    GBDVE said:
    Both overlay and config for the mcuboot are similar to the examples you indicated to me.

    The overlay and configs for SPI/QSPI external are different. 

    GBDVE said:
    As I previously reported, my problem is that the CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 seems to be ignored by the cmake system, as the final autoconf.h contains a value of 65536.

    You can check the build log to see why the value is ignored. Could you upload your project?

    GBDVE said:
    Is there something wrong in the cmake procedure I reported, or I'm missing something?

    I am not familiar with cmake build command. We usually suggest using "west build" or VS Code to build the project. See theBuilding and programming an application documentation.

    -Amanda H.

  • Hi Amanda, thanks for your reply.

    I've attached an example source based on my project. It contains the configurations to use the external flash on the SPI bus, not QSPI.

    I build it on a Linux environment, in the following way:

    $ mkdir build_test_mcuboot_extflash
    $ cd build_test_mcuboot_extflash
    $ cmake -B . -DBOARD=nrf5340dk_nrf5340_cpuapp -G"Eclipse CDT4 - Ninja"  ../test_mcuboot_extflash/
    $ west build

    The strange behavior I've explained in my previous post also happens when using "west build".

    The autoconf.h doesn't reflect the settings in mcuboot.conf:

    $ grep CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE mcuboot/zephyr/include/generated/autoconf.h
    $

    the CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE define is not present in the generated file.

    After having modified line 124 in the boards/nrf5340dk_nrf5340_cpuapp.conf, from CONFIG_MCUBOOT_IMAGE_VERSION="2.0.3+3" to CONFIG_MCUBOOT_IMAGE_VERSION="2.0.3+4", and after having reissued the "west build" command, then the autoconf.h contains the definitions in the mcuboot.conf, but the flash page value is wrong:

    $ grep CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE mcuboot/zephyr/include/generated/autoconf.h 
    #define CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE 65536
    

    I'm using Zephyr version v3.1.99-ncs1, nrf v2.1.0, mbedtls-nrf v3.1.0-ncs1.

    This is the test source code:

    test_mcuboot_extflash.zip

    Thank you.

    Regards,

    Gabriele.

  • Hi, 

    I see these relevant warnings in the build log

    warning: SPI_NOR (defined at drivers/flash/Kconfig.nor:4) was assigned the value 'y' but got the
    value 'n'. Check these unsatisfied dependencies: DT_HAS_JEDEC_SPI_NOR_ENABLED (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_SPI_NOR and/or look up SPI_NOR in the
    menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values,
    and KLoaded configuration 'C:/ncs/v2.1.0/zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig'
    Merged configuration 'C:/ncs/v2.1.0/bootloader/mcuboot/boot/zephyr/prj.conf'
    Merged configuration 'C:/ncs/v2.1.0/nrf/subsys/pcd/pcd.conf'
    Merged configuration 'C:/ncs/v2.1.0/nrf/subsys/bootloader/bl_override/override_external_mcuboot.conf'
    Merged configuration 'C:/ncs/v2.1.0/nrf/subsys/partition_manager/ext_flash_mcuboot_secondary.conf'
    config - Tips and Best Practices sections of the manual might be helpful too.
    
    
    warning: SPI_NOR_FLASH_LAYOUT_PAGE_SIZE (defined at drivers/flash/Kconfig.nor:56) was assigned the
    value '4096' but got the value ''. Check these unsatisfied dependencies: SPI_NOR (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE and/or look
    up SPI_NOR_FLASH_LAYOUT_PAGE_SIZE in the menuconfig/guiconfig interface. The Application Development
    Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual
    might be helpful too.
     

    For testing can you first try to make the flash test driver to work?

    https://github.com/nrfconnect/sdk-zephyr/tree/main/tests/drivers/flash

    In your case that want to use spi you can find these two files relevant:
    boards/nrf52840dk_flash_spi.conf
    boards/nrf52840dk_mx25r_high_perf.overlay
    (remove the 
    mxicy,mx25r-power-mode = "high-performance"; in your case from the .overlay)

    By modifying the .overlay file you should hopefully relatively quickly find configuration that works.

    -Amanda H.

  • Important Update: I've finally found the solution for the 4K flash page settings, and now the OTA works fine:

    in the case of mcuboot config, the CONFIG_SPI_NOR_SFDP_MINIMAL=n must be included in the mcuboot.conf.

    I looked at autoconf.h and noticed that it was set to yes, and probably when active, the other option CONFIG_SPI_NOR_SFDP_RUNTIME=n is ignored.

    It seems that the CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE parameter is considered only if those two options are disabled.

    After this modification, the OTA procedure works properly: the mcuboot recognizes the second image and does the swap.

    Many Thanks, Amanda, for your support. I'll check your suggestion in the next few days. Please consider that I've prepared the test code very quickly, and maybe there is something wrong, and its behavior may be different from the project I'm working on.

    Now, it remains to understand why the first build ignores the mcuboot configuration in the child_image dir.

    Regards,

    Gabriele.

Related