NVS strange performance; NVS needs to be primed/warmed up before it can be used

Hello and thank you for your time. I seem to be getting some incorrect performance from the flash memory with NVS, in that NVS needs to be primed or something before it works properly. I have been testing with this code:

void Prime_Flash()
{
    //now prime the file system, ive no idea why we need this but it works...
    const float test_value = 0xDEADBEEF; //random number, doesnt actually matter
    float read_value = 0;
    int i = 0;
    while ((i < 25) && (test_value != read_value)) //usually takes 12 tries
    {
        NUS_Send("Write %u %i \n", i, nvs_write(&fs, TEST_REGISTER_ID, &test_value, sizeof(test_value)));
        // nvs_write(&fs, TEST_REGISTER_ID, &test_value, sizeof(test_value));
        k_msleep(10);
        NUS_Send("Read %u %i \n", i, nvs_read(&fs, TEST_REGISTER_ID, &read_value, sizeof(read_value)));
        // nvs_read(&fs, TEST_REGISTER_ID, &read_value, sizeof(read_value));
        k_msleep(10);
        i++;
    }
    NUS_Send("Flash ready took %i tries \n",i);
}

And I get the following results:

Write 0 4
Read 0 -2
Write 1 4
Read 1 -2
Write 2 4
Read 2 -2
Write 3 4
Read 3 -2
Write 4 4
Read 4 -2
Write 5 4
Read 5 -2
Write 6 4
Read 6 4
Write 7 4
Read 7 4
Write 8 4
Read 8 4
Write 9 4
Read 9 4
Write 10 4
Read 10 4
Write 11 4
Read 11 4
Write 12 4
Read 12 4
Flash ready took 13 tries

This happens consistently, where it takes 13 tries before the flash can be used properly. As near as I can tell, once we get that Flash ready then everything works fine until the next reset. 

I initialize the flash with:

void Initialise_Flash()
{
    //prepare flash memory
    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);
    fs.offset = NVS_PARTITION_OFFSET;
    flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
    fs.sector_size = info.size;
    fs.sector_count = FLASH_SECTOR_COUNT;
    nvs_mount(&fs);
}

And it seems to work, I get the message

I: 2 Sectors of 4096 bytes
I: alloc wra: 0, f40
I: data wra: 0, 54

I have tried even comically large delays between initialising the flash and the first write, and between the write and read, and I still seem to have the error.

I am using the NRF5340 with SDK 2.5.0.

I doubt this is the expected behavior; do you have any suggestions what I am doing wrong?

Thanks!

  • Hi!

    Could you check what value the nvs_write and and nvs_read functions are returning ?

  • Hello and thank you for your reply; the right-most column of data represents what the write and read functions are returning:

    Write 0 4
    Read 0 -2
    Write 1 4
    Read 1 -2
    Write 2 4
    Read 2 -2
    Write 3 4
    Read 3 -2
    Write 4 4
    Read 4 -2
    Write 5 4
    Read 5 -2
    Write 6 4
    Read 6 4
    Write 7 4
    Read 7 4
    Write 8 4
    Read 8 4
    Write 9 4
    Read 9 4
    Write 10 4
    Read 10 4
    Write 11 4
    Read 11 4
    Write 12 4
    Read 12 4
    Flash ready took 13 tries

    Every write returns a 4, indicating 4 bytes have been written; this inherently indicates a problem, given that we are writing the same data to the same address, and would therefore expect a 0 after the first write.

    The reads start by returning -2, indicating there isnt even an entry in the flash register that that address exists. On read 6 we finally get a 4, indicating four bytes were read, but the data doesnt match the expected data, so another loop iteration is executed.

  • Hi!

    I found a similar report of this issue here:  Using NVS with Bluetooth Enabled 

    Maybe you can try the suggested workaround there, with using your own "userstorage" partition for nvs.

  • Thank you for your reply.

    Per your suggestion, I created a new partition for storing my data in flash. I want to do more testing but it seems everything is working.

    If I might make a suggestion, im sure other people will also want to use BLE and the NVS in the same project, perhaps NRF might consider some changes, although I admit im not sure what would be the best way to handle it, to avoid them having the same problem I did.

Related