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.

Parents
  • Hi, 

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

    DTS Partitioning is ignored with MCUboot. Use Partition Manager instead.

    I would suggest you use the SMP Server sample which also has support for LittleFS already. Here is my example smp_svr_nRF5340_ExternalFlash.7z for NCS v2.4.0.

    Beware that this code/configuration is not fully tested or qualified and should be considered provided “as-is”. Please test it with your application and let me know if you find any issues.

    Regards,
    Amanda H.

  • Hi Amanda, thanks for your reply.

    The example you shared with me won't compile,
    there are some config options undefined on the zephyr system.

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

    I tried to comment the config options that caused the failure:

    on prj.conf:
    #CONFIG_CRC=y
    #CONFIG_MCUMGR_GRP_OS_TASKSTAT=y
    #CONFIG_MCUMGR_GRP_IMG=y
    #CONFIG_MCUMGR_GRP_OS=y
    #CONFIG_MCUMGR_GRP_STAT=y

    on nrf5340dk_nrf5340_cpuapp.conf:
    #CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y

    With those modifications, the cmake command completes without errors, but the ninja build stops with the following:

    /opt/nordicsemi/ncs2/nrf/modules/mcuboot/hooks/nrf53_hooks.c: In function 'boot_read_image_header_hook':
    /opt/nordicsemi/ncs2/nrf/modules/mcuboot/hooks/nrf53_hooks.c:29:27: error: 'PM_CPUNET_APP_SIZE' undeclared (first use in this function)
       29 |   img_head->ih_img_size = PM_CPUNET_APP_SIZE;
          |                           ^~~~~~~~~~~~~~~~~~
    

    It seems related to something wrong with the PM. In other projects, the PM_CPUNET_APP_SIZE is automatically defined in the file zephyr/include/generated/pm_config.h and mcuboot/zephyr/include/generated/pm_config.h.

    Do you have any idea?

    Regarding this: "DTS Partitioning is ignored with MCUboot. Use Partition Manager instead." it was just a test I've made after previous failed tests using PM; I suppose the definition added in the overlay does nothing.

    Regards,
    Gabriele.

  • Hi, 

    For NCS v2.1.0, please use the board config and overlay file from my example in the previous reply to build with v2.1.0 smp_svr sample.

    -Amanda H.  

  • Hi Amanda, thank for your suggestion.

    I've successfully tested the smp_svr application on the external QSPI flash of the nrf5340-DK board.

    In my hardware, the external flash is connected on the SPI interface. After some debug, I've verified that the mcuboot can correctly access the SPI flash, but it fails with this error:

    <wrn> mcuboot: Cannot upgrade: not a compatible amount of sectors: 236 vs 15

    After some investigation, I've found that the following configuration in mcuboot.conf seems ignored by the build:

    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    

    The generated autoconf.h contains the following:

    #define CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE 65536

    I already checked that the CONFIG_FLASH_PAGE_LAYOUT=y is set, the same configuration used in mcuboot.conf its used in the app, and the autoconf.h of the app contains the correct declaration of the page size, set to 4096.

    I don't know how to force CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 in the mcuboot.conf, do you have any idea?

    Thank you.

Reply
  • Hi Amanda, thank for your suggestion.

    I've successfully tested the smp_svr application on the external QSPI flash of the nrf5340-DK board.

    In my hardware, the external flash is connected on the SPI interface. After some debug, I've verified that the mcuboot can correctly access the SPI flash, but it fails with this error:

    <wrn> mcuboot: Cannot upgrade: not a compatible amount of sectors: 236 vs 15

    After some investigation, I've found that the following configuration in mcuboot.conf seems ignored by the build:

    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    

    The generated autoconf.h contains the following:

    #define CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE 65536

    I already checked that the CONFIG_FLASH_PAGE_LAYOUT=y is set, the same configuration used in mcuboot.conf its used in the app, and the autoconf.h of the app contains the correct declaration of the page size, set to 4096.

    I don't know how to force CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 in the mcuboot.conf, do you have any idea?

    Thank you.

Children
  • GBDVE said:
    In my hardware, the external flash is connected on the SPI interface.

    The external SPI flash setting is different from the external QSPI flash of the nrf5340-DK board. 

    It would need an overlay file like this example and configs like this post

    -Amanda H.

  • 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.

Related