Storing a few parameter bytes in flash

I need to store just and handful of bytes in flash, some config data. Looking around the forum I've seen recommendation to read and write from/to by using the nvs functionality, but that looks massively overcomplicated at first glance. I don't need or want a filesystem. On an STM32 it's really simple and easy to put aside a sector and program data within it, without needing a file system you can do all that with just a handful of lines of code. Is it not possible to do the same with this chip?

Am using that VSC Zephyr setup and taken the central uart project to do my UART stuff after a lot of hand holding. Now I just want to save a few bytes of data at a particular point and then read that data at boot. Just six bytes.

How do I do this without the over complication of a file system please?

  • Hi

    Just so that I know, which version of NCS are you using?  In general I would say maybe check out the following sample https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/samples/subsys/nvs/README.html#nvs

    Here i think maybe you can use the setting partition as it is meant for storing persistent per device configuration and runtime states. Please see the documentation here, it also includes a example on how to use it

    Regards

    Runar

  • Yes, but this is the filesystem example which is what I'm questioning. Is this really the only way to write and read six bytes to/from flash memory?

  • True. Is this you want to write once or something you would like to update? 

    A coworker recommended having a look how it is done here, in the sample it's writing to UICR but it is same for to write to the flash. 

    Regards

    Runar

  • Might need to rewrite it, certainly need to give the possibility.

    That link seems to be totally irrelevant to what I'm trying to do. I've set up the example code to use

    nvs_write() but it returns -22.

    enum sys_status flash_user_write(uint8_t *data_ptr, size_t len)
    {
     
    ssize_t bytes_written;
    enum sys_status ret_val;

    bytes_written = nvs_write(&fs, MAC_ADDR_ID, data_ptr, len);
    if (len == bytes_written)
    ret_val = SYS_OK;
    else
    ret_val = SYS_FLASH_WR_ERR;

    return ret_val;

    }
    bytes_written is -22.
    fs is valid, MAC_ADDR_ID is set to 1. I've tried following the code in
    nvs_write but my eyes glaze over at things like multiple returns
    from a function (a BIG no-no),
    comments that don't match with the code, about fifty squillion function
    calls within function calls, returns like this Open mouth:

    return (addr >= boundary_start &&
    (addr < (boundary_start + boundary_size)) &&
    (len <= (boundary_start + boundary_size - addr)));
    and impossible to understand variable names.
    Again I'll say with the STM32 it's simple; you unlock flash to be
    written and do this for a 16-bit value:

    *(volatile u16 *)address = data_to_program;

    Unlocking the flash is three lines of code.

    You follow this nrf code though and it's mind boggling how convoluted it is.


  • Just for completeness' sake, this is how I initialise the flash, I'm blindly following the example code which makes little sense to me and I can find no documentation which explains how this initialisation is supposed to work.


    static struct nvs_fs fs;


    #define NVS_PARTITION storage_partition
    #define NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(NVS_PARTITION)
    #define NVS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(NVS_PARTITION)

    #define MAC_ADDR_ID 1

    int flash_init(void)
    {

    int ret_val;
    int rc = 0, cnt = 0, cnt_his = 0;
    struct flash_pages_info info;

    // Goodness knows what ret_val is all about, issues seem to return 0 in the example
    // code, so let's return 1 if all is well. Suspect it was due to poor programming
    // with multiple returns in the example code though, and is likely unecessary
    ret_val = 1;

    /* define the nvs file system by settings with:
    * sector_size equal to the pagesize,
    * 3 sectors
    * starting at NVS_PARTITION_OFFSET
    * Eh? What on earth is this on about?
    */
    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);
    ret_val = 0;
    }
    else
    {
    fs.offset = NVS_PARTITION_OFFSET;
    rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
    if (0 != rc)
    {
    printk("Unable to get page info, rc=%d\n", rc);
    ret_val = 0;
    }
    else
    {
    fs.sector_size = info.size;
    fs.sector_count = 3U;

    rc = nvs_mount(&fs);
    if (0 !=rc)
    {
    printk("Flash Init failed, rc=%d\n", rc);
    ret_val = 0;
    }
    }

    }

    return ret_val;

    }
Related