Problems with accessing storage_partition in an MCUBoot-enabled application under Zephyr

I've spent a couple days researching how to write a small amount of data to the storage_partition that is fairly standard in Nordic devicetrees. I haven't been successful and am looking for guidance.

My setup: nrf Connect SDK v2.2.0, Zephyr, nrf52840, using MCUBoot for DFU updates. I believe the fact that my application uses MCUBoot is the crucial bit of information.

Here's my board's Devicetree for the flash partitions.

&flash0 {
	 partitions {
		 compatible = "fixed-partitions";
		 #address-cells = <1>;
		 #size-cells = <1>;
 
		 boot_partition: partition@0 {
			 label = "mcuboot";
			 reg = <0x000000000 0x0000C000>;
		 };
		 slot0_partition: partition@c000 {
			 label = "image-0";
			 reg = <0x0000C000 0x00067000>;
		 };
		 slot1_partition: partition@73000 {
			 label = "image-1";
			 reg = <0x00073000 0x00067000>;
		 };
		 scratch_partition: partition@da000 {
			 label = "image-scratch";
			 reg = <0x000da000 0x0001e000>;
		 };
 
		 /*
		  * The flash starting at 0x000f8000 and ending at
		  * 0x000fffff is reserved for use by the application.
		  */
 
		 /*
		  * Storage partition will be used by FCB/LittleFS/NVS
		  * if enabled.
		  */
		 storage_partition: partition@f8000 {
			 label = "storage";
			 reg = <0x000f8000 0x00008000>;
		 };
	 };
 };

I am able to successfully build and run the following sample program for the nrf52840 DK. This sample does not assume MCUBoot is present.

https://github.com/nrfconnect/sdk-zephyr/blob/v3.2.99-ncs1-branch/samples/drivers/soc_flash_nrf/src/main.c

If I import this sample into my application and board, which includes MCUBoot, it fails. Note that I've changed "slot1_partition" to "storage_partition". It works completely fine if I leave TEST_PARTITION as "slot1_partition".  

#ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE
#define TEST_PARTITION	storage_partition
#else
#define TEST_PARTITION	storage_partition
#endif

#define TEST_PARTITION_OFFSET	FIXED_PARTITION_OFFSET(TEST_PARTITION)
#define TEST_PARTITION_DEVICE	FIXED_PARTITION_DEVICE(TEST_PARTITION)

#define FLASH_PAGE_SIZE   4096
#define TEST_DATA_WORD_0  0x1122
#define TEST_DATA_WORD_1  0xaabb
#define TEST_DATA_WORD_2  0xabcd
#define TEST_DATA_WORD_3  0x1234

#define FLASH_TEST_OFFSET2 0x41234
#define FLASH_TEST_PAGE_IDX 37

void main(void)
{
	const struct device *flash_dev = TEST_PARTITION_DEVICE;
	uint32_t buf_array_1[4] = { TEST_DATA_WORD_0, TEST_DATA_WORD_1,
				    TEST_DATA_WORD_2, TEST_DATA_WORD_3 };
	uint32_t buf_array_2[4] = { TEST_DATA_WORD_3, TEST_DATA_WORD_1,
				    TEST_DATA_WORD_2, TEST_DATA_WORD_0 };
	uint32_t buf_array_3[8] = { TEST_DATA_WORD_0, TEST_DATA_WORD_1,
				    TEST_DATA_WORD_2, TEST_DATA_WORD_3,
				    TEST_DATA_WORD_0, TEST_DATA_WORD_1,
				    TEST_DATA_WORD_2, TEST_DATA_WORD_3 };
	uint32_t buf_word = 0U;
	uint32_t i, offset;

	printf("\nNordic nRF5 Flash Testing\n");
	printf("=========================\n");

	if (!device_is_ready(flash_dev)) {
		printf("Flash device not ready\n");
		return;
	}
..... 

The primary symptom here is that TEST_PARTITION_DEVICE gets processed as NULL, so the device is null and the device_is_ready() test fails.

So to summarize, my MCUBoot-enabled project cannot access storage_partition. It can access slot1_partition.

I've looked into possibly using pm_static.yml, but when I define the storage partition there, my application images don't get placed in the flash.

It would be wonderful if there were a simple way I could add the definition of the storage_partition only, or even better, directly use the devicetree's specification of the storage_partition.

Thanks in advance for looking into this.

Best,

Steve

Parents
  • Hi Steve,

    When you enable MCUboot, the Partition Manager is automatically enabled.
    The Partition Manager overwrites the zephyr devicetree, so you can no longer use that.

    Generally, in the nRF Connect SDK, the storage partition is used by another file system. Ref flash_map_pm.h.

    Now, if you want to add a storage partition manually, the correct way would be to use pm_static.yml.
    And if you want MCUboot(a child image), you should use pm_static.yml either way. From Static configuration:

    "However, if you have a deployed product that consists of multiple images, where only a subset of the included images can be upgraded through a firmware update mechanism, the upgradable images must be statically configured. "

    To show how to add a storage partition using pm_static.yml, I took the hello world sample and added the following:

    prj.conf:

    CONFIG_BOOTLOADER_MCUBOOT=y

    pm_static.yml:

    storage:
      address: 0xfa000
      region: flash_primary
      size: 0x6000
    

    Is this what you were looking for?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Thank you for the fast and thorough reply.  

    I've added a pm_static.yml with only the storage partition specifications, and did a pristine build.  It builds cleanly. 

    When I go to install the build on my board via debug, I get a kernel panic in the MCUBOOT code.  

    BOOT_LOG_ERR("Unable to find bootable image"); 
    
    mcuboot_status_change(MCUBOOT_STATUS_NO_BOOTABLE_IMAGE_FOUND); 
    
    FIH_PANIC; 

    Are there additional steps I need to take to add the storage partition, but without affecting MCUBOOT?

    Thanks,

    Steve

  • When I add these configurations to hello_world, the project runs fine on an nRF52840DK.

    $ west build -t partition_manager_report
    -- west build: running target partition_manager_report
    [1/1] cd /home/sihe/ncs/zephyr/samples/hello_world/build && /usr/bin/python3.8 /home/...ager_report.py --input /home/sihe/ncs/zephyr/samples/hello_world/build/partitions.yml
      flash_primary (0x100000 - 1024kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x77000 - 476kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x76e00 - 475kB)-+
    | 0xc200: app (0x76e00 - 475kB)                   |
    +-------------------------------------------------+
    | 0x83000: mcuboot_secondary (0x77000 - 476kB)    |
    | 0xfa000: storage (0x6000 - 24kB)                |
    +-------------------------------------------------+
    
      sram_primary (0x40000 - 256kB): 
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+
    

    And logs:

    *** Booting Zephyr OS build v3.2.99-ncs1 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    *** Booting Zephyr OS build v3.2.99-ncs1 ***
    Hello World!
    

    Have you made any other configurations for the project?

    Try to build without "Debug configurations".

    How do you build and flash?

    Regards,
    Sigurd Hellesvik

Reply
  • When I add these configurations to hello_world, the project runs fine on an nRF52840DK.

    $ west build -t partition_manager_report
    -- west build: running target partition_manager_report
    [1/1] cd /home/sihe/ncs/zephyr/samples/hello_world/build && /usr/bin/python3.8 /home/...ager_report.py --input /home/sihe/ncs/zephyr/samples/hello_world/build/partitions.yml
      flash_primary (0x100000 - 1024kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x77000 - 476kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x76e00 - 475kB)-+
    | 0xc200: app (0x76e00 - 475kB)                   |
    +-------------------------------------------------+
    | 0x83000: mcuboot_secondary (0x77000 - 476kB)    |
    | 0xfa000: storage (0x6000 - 24kB)                |
    +-------------------------------------------------+
    
      sram_primary (0x40000 - 256kB): 
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+
    

    And logs:

    *** Booting Zephyr OS build v3.2.99-ncs1 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    *** Booting Zephyr OS build v3.2.99-ncs1 ***
    Hello World!
    

    Have you made any other configurations for the project?

    Try to build without "Debug configurations".

    How do you build and flash?

    Regards,
    Sigurd Hellesvik

Children
Related