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

Corrupted data using nrf_fstorage_write across page boundaries

Hi,

I am having some trouble using fstorage to write data into flash. I want to store ~20 kB of sampled data before processing it, and I am storing it just below the bootloader (in my case below 0x73000). When writing into this memory region using nrf_fstorage_write, all data written at addresses that are multiples of 0x1000 is corrupted. See below for a minimal working example (note that the softdevice is running, so the example should be tested in the context of ble_app_template). The example writes '0x22222222' to all words between 0x71F00 and 0x72100.

#define BOOTLOADER_START_ADDR 		0x00073000 // = NRF_UICR->NRFFW[0]

static void fstorage_evt_handler(nrf_fstorage_evt_t *p_evt) {
	if (p_evt->result != NRF_SUCCESS) {
		NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
		return;
	}
}

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
	{
		.evt_handler = fstorage_evt_handler,
		.start_addr  = (uint32_t)BOOTLOADER_START_ADDR - 0x4000,
		.end_addr    = (uint32_t)BOOTLOADER_START_ADDR};


void my_fstorage_init(void) {
	ret_code_t ret_code = nrf_fstorage_init(&fstorage, &nrf_fstorage_sd, NULL);
	APP_ERROR_CHECK(ret_code);

	uint32_t diff = fstorage.end_addr - fstorage.start_addr;
	NRF_LOG_DEBUG("my_fstorage_init: end address 0x%08x", fstorage.end_addr);
	NRF_LOG_DEBUG("my_fstorage_init: start address 0x%08x", fstorage.start_addr);
	NRF_LOG_DEBUG("my_fstorage_init: diff 0x%08x (%d)", diff, diff);
	NRF_LOG_FLUSH();
}

void my_fstorage_test() {

	ret_code_t ret_code;

	my_fstorage_init();

    uint32_t data[0x200];
    memset(data, 0x22222222, 0x200 * sizeof(uint32_t));

    ret_code = nrf_fstorage_write(
        &fstorage,
        0x71F00,
        data,
        0x200,
        NULL);
    APP_ERROR_CHECK(ret_code);
        
}

The corrupted data is obvious from an nrfjprog dump of the memory:

$ nrfjprog --memrd 0x00071F00 --n 0x00000200
0x00071F00: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F10: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F20: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F30: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F40: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F50: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F60: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F70: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F80: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071F90: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FA0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FB0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FC0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FD0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FE0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00071FF0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072000: 02200002 20020022 22222222 22222222   |.. .".. """"""""|
0x00072010: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072020: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072030: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072040: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072050: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072060: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072070: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072080: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x00072090: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720A0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720B0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720C0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720D0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720E0: 22222222 22222222 22222222 22222222   |""""""""""""""""|
0x000720F0: 22222222 22222222 22222222 22222222   |""""""""""""""""|

My setup:

  • SDK14.2
  • s132_nrf52_5.0.0
  • DFU bootloader from bootloader_secure_ble
  • GCC environment on Linux

I am sure I have simply misunderstood how the flash pages are handled by the memory controller or something, but I appreciate any help in resolving my issue.

Best regards,

Fredrik Flornes Ellertsen

  • As usual, I figured this out shortly after posting this question.

    For future reference: My code is based on ble_app_template, which uses the peer manager, which in turn uses FDS to store persistent information. FDS places its data just below the bootloader, and uses FDS_VIRTUAL_PAGES number of pages (3 by default, defined in sdk_config.h). The mangled data I saw on flash page boundaries are corrupted "magic values" used internally in FDS. When I move my own fstorage out of FDS space by subtracting FDS_VIRTUAL_PAGE_SIZE * FDS_VIRTUAL_PAGES * 4 number of bytes from the start and end addresses in the example above, the issue is fixed.

Related