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

FDS: Updating existing records with fds_record_update

I have been debugging this problem for a few days and have exhausted all of my options. I am relatively new to embedded development so user error is not out of the question.

To start, I am using SDK 11 and leveraging the experimental Flash Data Storage library on an nRF51422. I am able to read, write, and update records in a file but there is a catch. Updating a record only seems to work after I remove/reload the soft device(clear flash) through nRFgo Studio. In other words, if I start with a clean slate it all works fine and values are updated as expected, however, if I reset the device through the debugger, or re run the program, the updates never apply. It always remembers the very last write and won’t overwrite that value. The relevant code can be found below:

Flow:

First Run

  1. First write = fds_record_write

  2. All Subsequent writes go through fds_record_update

Result: All updates are performed as expected

Second Run

  1. Re run program:

  2. All writes, including the first, are handled through fds_record_update

Result: All updates succeed with FDS_SUCCESS, but value does not change. It always remembers the last value written from step 2.

Code:

void writeToFDSManager(void *dataToWrite, uint64_t byteCount) {

fds_record_t record;
fds_record_chunk_t record_chunk;
static fds_record_desc_t recordDesc;

record_chunk.p_data = dataToWrite;
/* See app_util for BYTES_TO_WORDS macro: (((n_bytes) + 3) >> 2 */
record_chunk.length_words = BYTES_TO_WORDS(byteCount);
record.file_id = fileDescriptor;
record.key = recordKey;
record.data.p_chunks = &record_chunk;
record.data.num_chunks = MAX_NUM_CHUNKS;

if (hasExistingRecord(recordDesc, fileDescriptor)) {
    fds_record_update(&recordDesc, &record);
} else {
    fds_record_write(&recordDesc, &record);
 }
}


void const *readFromFDSManager(void) {

fds_flash_record_t flash_record;
/* Per docs, always zero initialize */
fds_find_token_t ftok = {0};
fds_record_desc_t recordDesc;
	
	/* recordKey is hardcoded at the top of this file. If the user does not specify a fileId && recordKey, the
	   defaults are used. Currently set to 250 and 251 respectively */
	fds_descriptor_from_rec_id(&recordDesc, recordKey);
while (fds_record_find_by_key(recordKey, &recordDesc, &ftok) == FDS_SUCCESS) {
			/* Assignment of p_data via flash_record pointer */
    if (fds_record_open(&recordDesc, &flash_record) == FDS_SUCCESS) {
        fds_record_close(&recordDesc);
    }
}
return flash_record.p_data;
}

void fds_evt_handler(fds_evt_t const *const p_fds_evt) {
	
	switch(p_fds_evt->id) {
		case FDS_EVT_WRITE: {
			Foo *foo = (Foo *)readFromFDSManager();
			LOG("\n Write finished, new value is %u \n", foo->someId);
			break;
		}
		case FDS_EVT_UPDATE:{
			Foo *foo = (Foo *)readFromFDSManager();
			LOG("\n Update finished, new value is %u \n", foo->someId);
			break;
		}
		default:
			break;
	}
}

I will skip the initialization code, but the calls to read/update/write from main look like this:

    /* The docs state that we should hold onto the data until the write event is complete */
	static Foo foo;
for (int i = 0; i < 10; i++) {
	foo.someId = i;
	nrf_delay_ms(1000);
	writeToFDSManager((void *)&foo, sizeof(foo));
	nrf_delay_ms(2000);
}

Actual output log:

First run(After clearing flash via goStudio then reloading softDevice and application):

Write finished,  new value is 0 
Update finished, new value is 1
Update finished, new value is 2
Update finished, new value is 3
Update finished, new value is 4
Update finished, new value is 5
Update finished, new value is 6
Update finished, new value is 7
Update finished, new value is 8
Update finished, new value is 9

Second run(Restart debugger or restart program)

Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9
Update finished, new value is 9

I am leaving the majority of the methods,ret_code_t handling out for brevity but rest assured this works on a fresh softdevice/application stack on the first run. I have a theory as to why this fails on subsequent runs, but I might be off:

During a read/write record_chunk.p_data points to whatever address it is given. When the program is run a second time, that address has probably changed in which case maybe it can't find the correct address that points to the data to be updated?

Any help would be greatly appreciated.

Thanks!

Parents Reply Children
No Data
Related