This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

flashwrite persistence

Using sdk12.3 on pca10040.

I wanted to test persistence so I modified the example from the SDK as follows:  log what's already there.  don't erase.  enter new data.  log it again.

Using the provided example /peripheral/flashwrite to get the starting address

pg_size = NRF_FICR->CODEPAGESIZE;
pg_num = NRF_FICR->CODESIZE - 1; // Use last page in flash
addr = (uint32_t *)(pg_size * pg_num);

I then say:

flash_word_write(addr, (uint32_t)patwr);
NRF_LOG_INFO("'%c' was written to flash at %08x\r\n", patwr, (unsigned long) addr);
patrd = (uint8_t)*addr;
NRF_LOG_INFO("'%c' %08x was read from flash at %08x\r\n\r\n", patrd, *addr, (unsigned long) addr);

Regardless of the value of patwr (a character from the console) written to 0007F000 the read value is 00000000.

(So the fact that it does not persist across a reset is not surprising.)

Causes could be that the address is wrong or that writing to flash is somehow being blocked.

Any suggestions pls.

Parents Reply Children
  • Hello,

    The flash works in the way that you can only flip bits from 1 to 0. In order to flip them back to 1, you need to delete the entire flash page, unfortunately. This means that you need to somehow work around this, by figuring out where your latest data is written. 

    One way to work around this is to use the FDS module, which stores records with record IDs, which you can use to update a record, delete records, or write new records. 

    You can check out the guide in or documentation on how to use the FDS module.

    So there you would typically use functions like fds_record_write(), fds_record_delete(), fds_record_update(), and so on. The FDS module will also evenly distribute the flash tear, so it will ensure maximum durance for the flash.

    Best regards,

    Edvin

  • OK Thx Edvin.  I guess I saw flashwrite and not fds in the 12.3 examples and jumped to a conclusion. :-(

    I see that 12.3 does include the fds library so I made an example using the document you mention.

    The example talks about softdevice but I assume it should work without one.

    The first error I get is

    ../../../main.c:77:18: error: initializer element is not constant

    ret_code_t ret = fds_register(fds_evt_handler);

                      ^

    .. which seems odd.  Is this code viable in 12.3 with the 12.3 fds library?

    Thx.

  • Hello,

    The fds module should work without the softdevice as well. Just make sure to include the correct fstorage files (that are used by the fds files). 

    There are two fstorage.c files. One called fstorage.c, and one called fstorage_nosd.c (no softdevice). Use the last one.

    Your compiler error, "initializer element is not constant" is probably because you are trying to add 

    ret_code_t ret = fds_register(fds_evt_handler);

    outside a function.

    These instructions can't be copy-pasted into a main.c file. You must have all function calls inside a function, e.g. your main() function, or another function that you create. Something like this:

    static void fds_evt_handler(fds_evt_t const * p_fds_evt)
    {
        switch(p_fds_evt->id)
        {
            case FDS_EVT_INIT:
                if(p_fds_evt->result != FDS_SUCCESS)
                {
                    // initialization failed.
                }
                break;
            
            default:
                break;
        }
    }
    
    void my_fds_init_function(void)
    {
        ret_code_t ret = fds_register(fds_evt_handler);
        if(ret != FDS_SUCCESS)
        {
            //registering failed. 
        }
        ret = fds_init();
        if(ret != FDS_SUCCESS)
        {
            // Handle error.
        }
    }

    BR,

    Edvin

Related