Problems writing/reading struct to NVS

I've been slowly adding NVS functionality to my code.  Has been working fine, up until today when I attempted to write a struct I have for storing historical data to flash.

This is the struct:

struct log_data {
	// data structure to store individual strike events
	uint8_t	strike_level;  // SML = 1, MED = 2 or LRG = 4
	uint16_t	total_strike_count;  // Total number of strikes recorded to date
	struct bt_cts_current_time time_detected;  //Time stamp for each strike
};

I then have an array of this struct.  At this point, MAX_STRIKE_RECORDS = 10, but ultimately I want to see this at 250.

struct log_data lsr_strike_log[MAX_STRIKE_RECORDS];

In my code to read the data in from Flash, I have the following:

	uint32_t rc = 0;
	rc = nvs_read(&fs, HISTORY_ID, &lsr_strike_log, sizeof(lsr_strike_log));
	printk("sizeof = %u\n", sizeof(lsr_strike_log));
	printk("strike history rc = %u\n", rc);

The return value from nvs_read() is supposed to be the amount of data read in, if everything works as expected.  In my case, this should be equal to sizeof(lsr_strike_log), which is 160 bytes.  If the return value is larger than this, it apparently means there is more data to read in.  This is what I get from my two printk() statements:

sizeof = 160
strike history rc = 4294967294

So, its like the nvs_read() is going outside my defined flash area, or something - I'm not sure, hence why I'm posting here to see if someone can help me understand what's going on better.
My flash is initialised as per the following, and I don't get any of the error messages output via UART, so it appears to be initialising OK.
flash_dev = FLASH_AREA_DEVICE(STORAGE_NODE_LABEL);
	if (!device_is_ready(flash_dev)) {
		printk("Flash device %s is not ready\n", flash_dev->name);
		return -EINVAL;
	}
	fs.offset = FLASH_AREA_OFFSET(storage);
	rc = flash_get_page_info_by_offs(flash_dev, fs.offset, &info);
	if (rc) 
	{
		printk("Unable to get page info\n");
		return rc;
	}
	fs.sector_size = info.size;
	fs.sector_count = 3U;

	rc = nvs_init(&fs, flash_dev->name);
	if (rc) 
	{
		printk("Flash Init failed\n");
		return rc;
	}
If I enable CONFIG_LOG=y in my proj.config file, I see the following output:
I suspect I'm doing something obvious wrong. Problem is, its not obvious to me.
Thanks and regards,
Mike
  • OK, think I've answered a few of my questions:

    1. "storage" is defined in the .dts as

    storage_partition: partition@7a000 {
    			label = "storage";
    			reg = <0x0007a000 0x00006000>;
    		};

    The 0x80000 limit obviously corresponds to the offset of 0x7a000 and size of 0x6000.  I'm assuming I can't modify that to increase the storage area, as I'll run into issues with available flash?

    2. By moving the offset of user_storage to 0x7a000, I can get the extra space I would need, without running into issues with having to reduce the amount of settings_storage (which I think might be the cause of my BLE advertising issues, but I can't be sure).

    The question of why I run into storage issues when I appear to have plenty of space left is still baffling me though.  I'm assuming that the API's take care of things so that if I have 2000 bytes of data, I only need to consume 2000 bytes (or thereabouts) of flash.  I know when I was using the Cypress chips, their flash was arranged in blocks, and if I wanted to write one byte to flash, I actually needed to use up an entire row (up to 256 bytes depending upon the size of flash in the chip), unless I was able to shoe-horn all my data into a 256 byte array and then write it all to the one row.  Just thinking if the reason I get the -28 error when I've got more than 195 strike records has something to do with how the API's are arranging that data in flash

    Cheers,

    Mike

  • Earlier you said that CONFIG_PARTITION_MANAGER_ENABLED was set, which means that all the flash partitions in DTS are ignored, including the storage_partition you've attached in the previous reply.

    Have you disabled the Partition Manager since then? Could you upload your build folder, so I can check if the partition manager is enabled or not?

    Best regards,

    Simon

Related