Using Zephyr Flash library rather than NVS

Hi, 

I am currently using the NVS library with the nRF9160 and an external SPI-NOR flash device (MX25R6435F). I am getting concerned with the NVS library causing issues, and generally being quite slow, so I am exploring directly using the zephyr flash library to save and read flash. 

One of the reasons for this, is I only save log blocks of a known size that doesn't change - 4096 bytes. So using the allocation table in NVS for example, is a lot of wasted work - I can say flash block 'x' is at 'y' address. 

I assumed it would be a simple as using the functions flash_read() and flash_write(). I have used flash_erase() to erase the whole flash chip with NVS as it was A LOT quicker that using the nvs_clear(). 

What I find, is that although I get no errors, I cannot read back the bytes I write to an address, even though I can verify that its going into teh same SPI_NOR driver functions as NVS was, and I cannot understand what is different. 

Below is some example code. I never get an error so I can't work out what going wrong, but essentially I save a known array of data, then read it back, and it always reads 0. Some of the functions are other functions that I use in my code so wont work if you just copy and paste (Just the stuff to do with printing to terminal). 

int test_flash_block_save(struct device *dev, int num)
{
    err = flash_write(dev, (num * BLOCK_SIZE), &demo_flash_block, BLOCK_SIZE);
    if (!err)
    {
        char *str = malloc((BLOCK_SIZE*2));
        //Print the flash block in hex
        print_human_readable_hex(str, demo_flash_block, BLOCK_SIZE);
        print_to_com(uart_dev3, "[D] Flash Block - ", str, ALWAYS_PRINT);
        free(str);
        return 0;
    }
    return err;
}

int test_flash_block_read(struct device *dev, int num)
{
    int err = 0;
    err = flash_read(dev, (num*BLOCK_SIZE),  &temp_data, BLOCK_SIZE);
    if(!err)
    {
        char *str = malloc((BLOCK_SIZE*2));
        print_human_readable_hex(str, temp_data, BLOCK_SIZE);
        print_to_com(uart_dev3, "[D] Flash Block - ", str, ALWAYS_PRINT);
        free(str);
        return 0;
    }
    return err;
}

/*  In Main */

flash_dev = DEVICE_DT_GET(DT_N_NODELABEL_mx25r64);

test_flash_block_save(flash_dev, 0);
test_flash_block_read(flash_dev, 0);

/*  end   */

Any suggestions would be useful. 

SDK 1.6.1 - Modem FW 1.3.0 - Own design PCB

Thanks, 

Damien

  • I just tested the sample spi_flash with the board selection nrf9160dk_nrf9160_ns v0.14.0 (that revision will enable external flash) and NCS v2.0.0.

    I used the board nRF9160 DK v1.0.1

    I also created a file \zephyr\samples\drivers\spi_flash\boards\nrf9160dk_nrf9160_ns.conf and added CONFIG_SPI_NOR=y.

    I got the following output:

    *** Booting Zephyr OS build v3.0.99-ncs1  ***
    
    JEDEC SPI-NOR SPI flash testing
    ==========================
    
    Test 1: Flash erase
    Flash erase succeeded!
    
    Test 2: Flash write
    Attempting to write zu bytes
    Data read matches data written. Good!!

    Which means that I'm successfully able to read and write to external flash using the API zephyr/drivers/flash.h

    I see now that you're using NCS v1.6.0. Let me know if the above works on that version too.

    Best regards,

    Simon

  • Ohhh this is embarrassing ... 

    I think I must have been tired yesterday - I totally forgot the fact that in my old code, before I initialised the NVS library I also pulled up the write protect pin. 

    I just tried pulling that pin up and it worked straight away. 

    Sorry to waste your time - and thank you for your answer Simon!

    Thanks, 

    Damien

Related