Zephyr NVS on an nRF5340_DK

Hi

I am trying to get the Zephyr NVS working on an nRF5340_DK board.

I am using the notes here:


And my starting code is based on the example it references:

In nrf5340_cpuapp_common.dts, the flash partitions are defined as follows:

&flash0 {

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

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 0x00010000>;
		};
		slot0_partition: partition@10000 {
			label = "image-0";
		};
		slot0_ns_partition: partition@50000 {
			label = "image-0-nonsecure";
		};
		slot1_partition: partition@80000 {
			label = "image-1";
		};
		slot1_ns_partition: partition@c0000 {
			label = "image-1-nonsecure";
		};
		scratch_partition: partition@f0000 {
			label = "image-scratch";
			reg = <0x000f0000 0xa000>;
		};
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0x000fa000 0x00006000>;
		};
	};
};

The nRF5340, the Flash page size is 4096 bytes (0x1000). So I decided to define two sectors (I think what should then happen is: when the first sector is full, NVS will then use the second sector. When the second sector is full, it will erase the first sector and use it. I am not sure if we can use just one sector.)

So to reserve some space (two sectors, total size 0x2000) in the storage_partition, I added the following to the app.overlay file:

&flash0 {
	partitions {
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0x000fa000 0x00004000>;
		};
		user_partition: partition@fe000 {
			label = "user_storage";
			reg = <0x000fe000 0x00002000>;
		};
	};
};

Now here’s my code:

uint32_t nvs_var_1;
#define NVS_VAR_1_ID 1


int nvs_data_init() {

	struct flash_pages_info info;
	const struct device *flash_dev;
	int rc = 0;
	ssize_t num_bytes;

	// See if can use the Flash
	
	flash_dev = DEVICE_DT_GET(FLASH_NODE);

	if (!device_is_ready(flash_dev))
	{
		printk("Flash device %s is not ready\n", flash_dev->name);
		return (-1);
	}

	fs.offset = FLASH_AREA_OFFSET(storage);

	printk("fs offset %d\n", fs.offset);

	rc = flash_get_page_info_by_offs(flash_dev, fs.offset, &info);
	if (rc)
	{
		printk("Unable to get page info\n");
		return (-2);
	}

	fs.sector_size = info.size;
	fs.sector_count = 2U;

	printk("size: %d, total: %d\n", info.size, info.size * 2);

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

	// See if can read the data from the Flash

	if (fs.ready) {
		printk("ready to read\n");
	}

	rc = nvs_read(&fs, NVS_VAR_1_ID, &nvs_var_1, sizeof(nvs_var_1));
	if (rc > 0)
	{ // item was found, show it
		printk("Id: %d, nvs_var_1: %d\n",  NVS_VAR_1_ID, nvs_var_1);
	}
	else
	{ // item was not found, add it
		printk("imme_data_init: nvs_var_1 not found (rc = %d), adding it at id %d\n", rc, NVS_VAR_1_ID);
		nvs_var_1 = 99;
		if (fs.ready) {
			printk("ready to write\n");
		}		
		num_bytes = nvs_write(&fs, NVS_VAR_1_ID, &nvs_var_1, sizeof(nvs_var_1));
		printk("imme_data_init: num bytes written: %d\n", num_bytes);
	}

	return (0);

}

PROBLEM:

When I run this code, the nvs_read() function returns -2 (ENOENT: No such file or directory).
The nvs_write() function always return 4, indicating that 4 bytes have been written.

If I initiate a soft system reset or press the reset button n the board, I get the same results – i.e. each tie the code runs, the nvs_read() function returns -2

So it looks like the code is not defining / accessing the user_partition correctly

Regards

Garrett

  • Hi Vidar

    You inadvertently solved my problem.
    In my existing project, I modified the pm_static.yml from:

    storage:
      address: 0xfa000
      size: 0x4000
      end_address: 0xfe000
      placement:
      before:
      - storage
      region: flash_primary
    user_storage:
      address: 0xfe000
      size: 0x2000
      end_address: 0x100000
      placement:
      before:
      - end
      region: flash_primary
    

    to this:

    user_storage:
      address: 0xfe000
      size: 0x2000
      end_address: 0x100000
      placement:
      before:
      - end
      region: flash_primary
    
    

    And everything worked :)

    So the issue was that I must have been messing up the existing ‘storage’ allocation/definition, and once I removed it from the .yml file, it must be happy with what ever default settings it has from elsewhere.

Related