Setting and using NVS and BT Settings with Static Partition Manager

Hi!
We are currently in the process of migrating our nrf5 SDK code to NCS, on nrf52833-based hardware.
After being stuck for a while on the basic init process of MCUBoot, I was finally able to get MCUBoot to run our app (see previous ticket RE: MCUBoot, Zephyr, and static partition manager - Thanks Sigurd for all your help!). 

My problem currently is that all the MCUBoot changes, most specifically the Static Partition Manager, have caused our app to consistently fail on boot with the following error:

 "bt_settings: settings_subsys_init failed (err -45)".

Reading up on this, err 45 = EDEADLK (https://docs.zephyrproject.org/apidoc/latest/group__system__errno.html#ga55cc70ce0ba661298f3c412095dfeeb6), which is "Resource deadlock avoided".

Before all the changes leading to MCUBoot + PM, I had been able to init and use the NVS without issues, as well as the BT settings init.

Pre-MCUBoot and PM, I had defined our flash like so (in overlay):

/delete-node/ &storage_partition;
&flash0 {

	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;
		
		...
        
		settings_partition: partition@77000 {
			label = "settings";
			reg = <0x00077000 0x00002000>;
		};
        storage_partition: partition@79000 {
			label = "storage";
			reg = <0x00079000 0x00007000>;
		};
	};
};

With chosen as follows (same overlay file):

/{
    chosen {
    ...
        zephyr,settings-partition = &settings_partition;
    };
};

And our NVS init code is as follows:

#define NVS_PARTITION		storage_partition
#define NVS_PARTITION_DEVICE	FIXED_PARTITION_DEVICE(NVS_PARTITION)
#define NVS_PARTITION_OFFSET	FIXED_PARTITION_OFFSET(NVS_PARTITION)

static struct nvs_fs fs;

void flash_manager_init()
{
    int rc=0;
	struct flash_pages_info info;

	/* define the nvs file system by settings with:
	 *	sector_size equal to the pagesize,
	 *	3 sectors
	 *	starting at NVS_PARTITION_OFFSET
	 */
	fs.flash_device = NVS_PARTITION_DEVICE;
	if (!device_is_ready(fs.flash_device)) {
		printk("Flash device %s is not ready\n", fs.flash_device->name);
		return;
	}
	fs.offset = NVS_PARTITION_OFFSET;
	rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
	if (rc) {
		printk("Unable to get page info\n");
		return;
	}
	fs.sector_size = info.size;
	fs.sector_count = 4U;

	rc = nvs_mount(&fs);
	if (rc) {
		printk("Flash Init failed\n");
		return;
	}
}

Our new pm_static.yml file is:

app:
  address: 0x9200
  end_address: 0x40000
  region: flash_primary
  size: 0x36e00
mcuboot:
  address: 0x0
  end_address: 0x9000
  placement:
    before:
    - mcuboot_primary
  region: flash_primary
  size: 0x9000
mcuboot_pad:
  address: 0x9000
  end_address: 0x9200
  placement:
    align:
      start: 0x1000
    before:
    - mcuboot_primary_app
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0x9000
  end_address: 0x40000
  orig_span: &id001
  - mcuboot_pad
  - app
  region: flash_primary
  sharers: 0x1
  size: 0x37000
  span: *id001
mcuboot_primary_app:
  address: 0x9200
  end_address: 0x40000
  orig_span: &id002
  - app
  region: flash_primary
  size: 0x36e00
  span: *id002
mcuboot_secondary:
  address: 0x40000
  end_address: 0x77000
  placement:
    after:
    - mcuboot_primary
    align:
      start: 0x1000
  region: flash_primary
  share_size:
  - mcuboot_primary
  size: 0x37000
settings_partition:
  address: 0x77000
  end_address: 0x79000
  placement:
    align:
      start: 0x1000
  region: flash_primary
  size: 0x2000
storage_partition:
  address: 0x79000
  end_address: 0x80000
  placement:
    align:
      start: 0x1000
  region: flash_primary
  size: 0x7000
sram_primary:
  address: 0x20000000
  end_address: 0x20020000
  region: sram_primary
  size: 0x20000

I have tried to change the number of sectors to 7 to match the 7 sectors for storage_partition in the pm_static.yml, to no avail (same -45 error).

My questions are as follows:

  • How do I go about replacing the "zephyr,settings-partition = &settings_partition;" once I remove the flash0 override from our overlay file?
  • How do I go about pointing from my code (like the existing NVS_PARTITION define) to the PM partitions for nvs init, if possible?
  • If not possible - how do I go about initing and using nvs?

Thanks!

Roi

Parents Reply Children
  • Thanks Sigurd!
    Per your suggestion on my previous ticket, I have tried to remove DTS flash partitions and "chosen" for settings_partition, and the app now works, but LTK is not saved for next connection.
    Perhaps there is some way to explicitly direct "zephyr,settings_partition" at flash memory by address (ie - partition @ address) ?

    Thanks!

    Roi

  • Hi Roi,

    Reading through your case above, I realize that it can be hard to give debugging tips for projects with a lot of moving parts.
    So I will propose another way to do it: You give me a description of a simple project that has the features you need, and I will try to configure it for you.

    What I need to know:

    Bluetooth LE base sample (from BLE samples):

    • <Sample name>

    Feature list:

    • (example) MCUboot
    • (example) NVS
    • etc

    How does that sound to you?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Thanks very much for the suggestion!!
    I have opened a private ticket with what you have requested.
    Thanks again!
    Roi

  • Please do not change conversation to private because I have the same problem as you do, and presume many others too.

    I am using DFU (Partition manager with static partitions defined in the partitions.yml file) with NVS storage code where I need to read/write values in non-volatile storage. When I enable DFU (Partition manager), the partition DTS node in flash0 node of soc defined in board DTS becomes not true because the partitions from partitions.yml file are included so the code under zephyr/samples/subsys/nvs/src/main.c (which your code uses), does not work anymore.

    In partitions.yml file located under the build folder, I have nvs_storage node prepended (not by me) at the address 0x3f000 with size 0x6000.

    Now, the question is how do I reference nvs start address in the sample code?

  • Ok I think I've managed to get it working.

    If you look into partitions.yml file under build folder, cou can see that the nvs_storage start address is at 0x3f000. If you search that address in all files under build folder, you can find that the PM_NVS_STORAGE_ADDRESS macro defined in build\zephyr\include\generated\pm_config.h file is the start address of the NVS storage. With that, you can populate the fs.offset variable.

    To get the flash device binding, again found in the build\zephyr\include\generated\pm_config.h file, the PM_NVS_STORAGE_DEV_NAME macro includes NVS storage device name. With it, you can populate the fs.flash_device variable by calling device_get_binding(PM_NVS_STORAGE_DEV_NAME) function.

Related