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?

Parents Reply Children
  • 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;

    }
  • So, trawling through endless posts here, it seems maybe you can't just reference this nvs code and you need to add something to this .dts file thing. I've tried looking through some more example files and looks like maybe you need something like this:

    &flash0 {

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

            boot_partition: partition@0 {
                label = "mcuboot";
                reg = <0x00000000 0x0000C000>;
            };
            slot0_partition: partition@c000 {
                label = "image-0";
                reg = <0x0000C000 0x00076000>;
            };
            slot1_partition: partition@82000 {
                label = "image-1";
                reg = <0x00082000 0x00076000>;
            };

            /*
             * The flash starting at 0x000f8000 and ending at
             * 0x000fffff is reserved for use by the application.
             */

            /*
             * Storage partition will be used by FCB/LittleFS/NVS
             * if enabled.
             */
            storage_partition: partition@f8000 {
                label = "storage";
                reg = <0x000f8000 0x00008000>;
            };
        };
    };

    But if I put that in mine it stops compiling. Can I even  just take another flash segment from a different project's dts file?

  • I feel like I'm shouting into the void. More investigation seems like maybe I need one of these overlay files? With something like this:

    /delete-node/ &storage_partition;

    &flash0 {
        partitions {
            /* Set 48KB of storage at the beginning of bank2 in order to have 3 sectors smaller than 32K
             *     (nvs.h: uint16_t sector_size)
             */
            storage_partition: partition@100000 {
                label = "storage";
                reg = <0x000100000 DT_SIZE_K(48)>;
            };
        };
    };

    Is that right? If so, which one? I finally worked out how to make a new project with a 52840 using nvs project and the dts file has this:

    &flash0 {
    /*
    * For more information, see:
    */
    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    boot_partition: partition@0 {
    label = "mcuboot";
    reg = <0x000000000 0xd000>;
    };
    slot0_partition: partition@d000 {
    label = "image-0";
    reg = <0x0000d000 0x30000>;
    };
    slot1_partition: partition@3d000 {
    label = "image-1";
    reg = <0x0003d000 0x1000>;
    };
    storage_partition: partition@3e000 {
    label = "storage";
    reg = <0x0003e000 0x00002000>;
    };
    };
    };

    So could I create a custom overlay file with this in?
    Would I need all the guff or just this:

    storage_partition: partition@3e000 {
    label = "storage";
    reg = <0x0003e000 0x00002000>;

    ?
    I just can't get my head around how my original project doesn't complain
    I don't seem to have
    storage_partition
    defined anywhere. What's the score here?

    Any chance of some guidance here please?
  • A little more shouting into the void. Tried putting this in an overlay file

    /delete-node/ &storage_partition;

    &flash0 {
    partitions {
    /* Set 48KB of storage at the beginning of bank2 in order to have 3 sectors smaller than 32K
    * (nvs.h: uint16_t sector_size)
    */
    storage_partition: partition@f8000 {
    label = "storage";
    reg = <0x000f8000 0x00008000>;
    };
    };
    };
    No difference, still -22 error.
Related