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
  • 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?

  • 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.
  • Hello, earth calling Nordic. Is there no-one there who can offer some assistance on this? I can see no difference between any of the config files in a plain write to flash demo (which works) and my modified central uart demo (which just returns -22 error. I've spent a week trying to get six bytes written to on-chip flash,this is madness.

  • Hello,

    Presuming you reserve a flash page (either in an dts overlay or using partition manager (if partition manager is enabled the partitioning is done in pm_static.yml file (dts is ignored))).

    Then in theory you should be able to do something like:

    #define FLASH_ADDR 0x000F8000
    
    uint32_t value;
    
    // Read value
    value = *((volatile uint32_t *)FLASH_ADDR);
    
    // Erase page
    (void) nrfx_nvmc_page_erase(FLASH_ADDR);
    
    //Write value
    nrfx_nvmc_word_write(FLASH_ADDR, value);

    Kenneth

  • Hi, thanks, finally came back to this project after giving up on it and this provides the answer I need. Wasted a lot of time on the first, incorrect one.

    Many thanks for that.

Reply Children
  • I have a question about this. Having seemingly got to just about being ready to give this to a customer for beta testing, it's more often than not crashing when I call:

    nrfx_nvmc_page_erase
    DuckDuckGoing about I have seen some
    suggestions that you cannot use nrfx_nvmc_page_erase when
    you're using the soft device.

    Is that true? I can't really see how you could use any
    Nordic product without using soft device, so it seems unlikely
    but maybe I'm missing something. Maybe I don't understand
    properly what the soft device is.

    I'm using an nrf52840 with Zephyr as the OS, based on nrf Connect SDK2.0 and
    using BLE with the 52840 acting as a central device.

    So, can I actually *not* use nrfx_nvmc_page_erase()
    in this scenario?

    If that is the case, I need to reask my question
    from half a year ago:

    How do I store six bytes of data in internal flash please? The
    advice given by Kenneth seemed perfect, but now I have other
    aspects of the system going and I try to erae a sector it's all going wrong.

    If Kenneth's method *is* suitable for my setup, any idea
    why it might by crashing in
    nrfx_nvmc_page_erase() please?
  • Hello,

    You can't use the direct nvmc while actively advertising or in a connection no. So to workaround this there are two solutions:

    1. Disconnect BLE for a short period of time to store the data.

    2. Use timeslot to request a short period of time where you can use nvmc directly:
    https://docs.nordicsemi.com/bundle/ncs-2.0.0/page/nrfxlib/mpsl/doc/timeslot.html 

    If you are interested in timeslot there is an old example here (this allow running a different radio protocol (ESB) in the timeslot, in your case you want to do the flash write instead), it may possible still be of use: https://github.com/too1/ncs-esb-ble-mpsl-demo 

    If you want to erase you need a 100ms window.

    Kenneth

Related