(Zephyr / NCS) NVS Error: flash_nrf: invalid address: with CONFIG_SETTINGS=y

I am trying to implement bonded pairing with a project in which I already have NVS configured for user data. When implementing bonding, I understand that I need to remove the CONFIG_SETTINGS_NONE=y flag and add a CONFIG_SETTINGS=y flag. I assume this is to store the bond information on the device in persistent storage.

However, when I remove CONFIG_SETTINGS_NONE from my project, my NVS reads start to fail. The error I am receiving is below:

[00:01:02.705,261] <err> flash_nrf: invalid address: 0x00080ff8:8

Here is how I start my NVS driver:

#define STORAGE_NODE DT_NODE_BY_FIXED_PARTITION_LABEL(storage)
#define FLASH_NODE DT_MTD_FROM_FIXED_PARTITION(STORAGE_NODE)

user_config_data_t user_config_data;

static struct nvs_fs fs;

void load_user_data(void)
{
	int rc_flash;
	struct flash_pages_info info;
	const struct device *flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));
	/* define the nvs file system by settings with:
	 *	sector_size equal to the pagesize,
	 *	3 sectors
	 *	starting at FLASH_AREA_OFFSET(storage)
	 */
	if (!device_is_ready(flash_dev))
	{
		printk("Flash device %s is not ready\n", flash_dev->name);
		return;
	}
	fs.offset = FLASH_AREA_OFFSET(storage);
	rc_flash = flash_get_page_info_by_offs(flash_dev, fs.offset, &info);
	if (rc_flash)
	{
		printk("Unable to get page info\n");
		return;
	}
	fs.sector_size = info.size;
	fs.sector_count = 3U;

	rc_flash = nvs_init(&fs, flash_dev->name);
	if (rc_flash)
	{
		printk("Flash Init failed\n");
		return;
	}

	/* LONG_ID is used to store a larger dataset ,lets see if we can read
	 * it from flash
	 */
	rc_flash = nvs_read(&fs, USER_DATA_ADDRESS, &user_config_data, sizeof(user_config_data));
	if (rc_flash > 0)
	{
		printk("User data found!\n");
		... do stuff
	}
	else
	{
		/* entry was not found, add it if reboot_counter = 0*/
		printk("User data not found, adding it as id %d\n", USER_DATA_ADDRESS);
	    ... do stuff
	}
}

Below is my flash0 node in my custom board dts file.

&flash0 {

	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 0xc000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0x0000C000 0x32000>;
		};
		slot1_partition: partition@3e000 {
			label = "image-1";
			reg = <0x0003E000 0x32000>;
		};
		scratch_partition: partition@70000 {
			label = "image-scratch";
			reg = <0x00070000 0xa000>;
		};
		storage_partition: partition@7a000 {
			label = "storage";
			reg = <0x0007a000 0x00006000>;
		};
	};
};

I have a feeling it has something to do with the settings_partition and it eating up my storage NVS offset. I do not know how to fix this though as calculating flash partitions is new to me.

Parents
  • Hi

    The Partition Manager documentation is available here. I'm not sure what you're looking for in terms of "calculating partitions", but the size of Flash and RAM is stated in the nRF52 product specification, and the size of I.E. the Bluetooth LE controller you're using can be found here.

    Best regards,

    Simon

  • So it seems that my issue is due to using MCUBoot in combination with NVS. I understand that the device tree is ignored when using a multi-image build configuration.

    This can be re-created by trying to compile the NVS sample with CONFIG_BOOTLOADER_MCUBOOT=y set. The problem line is below and is because the macro cannot find the storage label which was defined in the device tree (being ignored).

    #define STORAGE_NODE DT_NODE_BY_FIXED_PARTITION_LABEL(storage)
    #define FLASH_NODE DT_MTD_FROM_FIXED_PARTITION(STORAGE_NODE)
    flash_dev = DEVICE_DT_GET(FLASH_NODE);

    Here is the error:

    error: '__device_dts_ord_DT_COMPAT_fixed_partitions_LABEL_nvs_storage_PARENT_PARENT_ORD' undeclared (first use in this function)
       80 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)

    I am able to fix the compilation error by adding a pm_static.yml file to the root directory of the NVS sample as described far down in this thread.

    storage:
      address: 0x7a000
      size: 0x6000
      end_address: 0x80000
      placement:
        before: 
        - user_storage
      region: flash_primary
    user_storage:
      address: 0x80000
      size: 0x2000
      end_address: 0x82000
      placement:
        before:
        - end
      region: flash_primary

    However, in a different thread (that I cannot find right now), it is recommended to avoid static configuration. This seems to make sense.

    So in order to prefer the partition manager's output, I have removed the two problems lines (above) and ran a `ninja report` in the build folder. The output is below:

      flash_primary (0x80000 - 512kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x37000 - 220kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x36e00 - 219kB)-+
    | 0xc200: app (0x36e00 - 219kB)                   |
    +-------------------------------------------------+
    | 0x43000: mcuboot_secondary (0x37000 - 220kB)    |
    | 0x7a000: nvs_storage (0x6000 - 24kB)            |
    +-------------------------------------------------+
    
      sram_primary (0x10000 - 64kB): 
    +-------------------------------------------+
    | 0x20000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

    This seems to imply that there is a partition labeled `nvs_storage` that I can use as a FLASH_NODE.

    However, when changing my problem lines to target the partition labeled nvs_storage (as described in the report output) I am still faced with the same compilation error.

    I do not see any documentation on the partition manager page that describes how to actually use it in the multi-image builds. Am I missing something? What is the alternative to defining a static partition?

Reply
  • So it seems that my issue is due to using MCUBoot in combination with NVS. I understand that the device tree is ignored when using a multi-image build configuration.

    This can be re-created by trying to compile the NVS sample with CONFIG_BOOTLOADER_MCUBOOT=y set. The problem line is below and is because the macro cannot find the storage label which was defined in the device tree (being ignored).

    #define STORAGE_NODE DT_NODE_BY_FIXED_PARTITION_LABEL(storage)
    #define FLASH_NODE DT_MTD_FROM_FIXED_PARTITION(STORAGE_NODE)
    flash_dev = DEVICE_DT_GET(FLASH_NODE);

    Here is the error:

    error: '__device_dts_ord_DT_COMPAT_fixed_partitions_LABEL_nvs_storage_PARENT_PARENT_ORD' undeclared (first use in this function)
       80 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)

    I am able to fix the compilation error by adding a pm_static.yml file to the root directory of the NVS sample as described far down in this thread.

    storage:
      address: 0x7a000
      size: 0x6000
      end_address: 0x80000
      placement:
        before: 
        - user_storage
      region: flash_primary
    user_storage:
      address: 0x80000
      size: 0x2000
      end_address: 0x82000
      placement:
        before:
        - end
      region: flash_primary

    However, in a different thread (that I cannot find right now), it is recommended to avoid static configuration. This seems to make sense.

    So in order to prefer the partition manager's output, I have removed the two problems lines (above) and ran a `ninja report` in the build folder. The output is below:

      flash_primary (0x80000 - 512kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x37000 - 220kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x36e00 - 219kB)-+
    | 0xc200: app (0x36e00 - 219kB)                   |
    +-------------------------------------------------+
    | 0x43000: mcuboot_secondary (0x37000 - 220kB)    |
    | 0x7a000: nvs_storage (0x6000 - 24kB)            |
    +-------------------------------------------------+
    
      sram_primary (0x10000 - 64kB): 
    +-------------------------------------------+
    | 0x20000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

    This seems to imply that there is a partition labeled `nvs_storage` that I can use as a FLASH_NODE.

    However, when changing my problem lines to target the partition labeled nvs_storage (as described in the report output) I am still faced with the same compilation error.

    I do not see any documentation on the partition manager page that describes how to actually use it in the multi-image builds. Am I missing something? What is the alternative to defining a static partition?

Children
No Data
Related