Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Writing and reading from flash on nRF52832, read always returns erased memory value

Hi,

I am working at a project that was abandoned by a guy that worked on my position. I have to fix some issues and add some features. I'm using SDK 17.0.2, my IDE is VSCodium (VSCode) under Linux. In sdk_config.h I have the NRF_FSTORAGE_ENABLED set to 1.

My current problem is that I have to save data received via Bluetooth into flash memory using fstorage. Right now I am able to init and erase the memory I want, but I have a problem writing it. The function nrf_fstorage_write returns NRF_SUCCESS but value read by nrf_fstorage_read is always at the stage of erase (0xFFFF FFFF). I know that I have to wait for the flash memory erase/write function to wait and I am using while loop to achieve that (see the code). Second AND subsequent runs of this function return as a result of read a value of decimal 536 871 096.

My target in this function is to just to write received data to flash, but currently I have to check if it was saved properly as it is at the development stage. Function nrf_fstorage_write is used in another place in the code but in a local function and I don't want to touch this working part (as I said I'm fixing someone else's code and it partially looks like spaghetti style), refactoring will come later.

Below I present you a dummy function that I use.

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
	.start_addr = 0x70000,
	.end_addr = 0x71000,
};

static void function()
{
    //init
    nrf_fstorage_init(&fstorage, &nrf_fstorage_sd, NULL);
    
    //erase
    uint32_t result_erase = nrf_fstorage_erase(&fstorage, fstorage.start_addr, 1, NULL); // erase 1 page
    while (result_erase != NRF_SUCCESS)
	{
		(void) sd_app_evt_wait();
	}
    
    //write
    uint32_t blabla[] = {(uint32_t)123};
    uint32_t result_write = nrf_fstorage_write(&fstorage,
											fstorage.start_addr,
											blabla, 
											sizeof(blabla),
											NULL);
	while (result_write != NRF_SUCCESS)
	{
		(void) sd_app_evt_wait();
	}
	NRF_LOG_INFO("\twrite result: %d\n", result_write);
	
	//read
	uint32_t temporary_buffer[1];
	uint32_t result_read = nrf_fstorage_read(&fstorage, fstorage.start_addr, temporary_buffer, sizeof(blabla));
	NRF_LOG_INFO("\tsaved %d read %d", blabla[0], temporary_buffer[0]);
	NRF_LOG_INFO("\tread result: %d", result_read);
}

Why it does not work as it should? What am I doing wrong?

  • When using softdevice, all write ops are buffered and will be executed by the SD later (when it does not have radio stuff scheduled). Your read call will be executed before that can happen.

  • That is correct. Also, I see that you added a line to wait (sd_app_evt_wait()) but this call will just wait for any event, and not necessarily the "flash write done" event. 

    From the flash_fstorage example in SDK\examples\peripheral\flash_fstorage, see how wait_for_flash_ready(&fstorage); is used to wait for write and erase calls.

    Best regards,

    Edvin

Related