Flash Data Storage (FDS) fds_record_update() -> Reset -> Two valid records possible?

  • SDK: 15.2
  • SoftDevice: s140_nrf52_6.1.0
  • FreeRTOS
  • Hardware: nRF52840 (Custom boards)

Note: I have ported all fixes for FDS from SDK 17.1.0 to my SDK (15.2).

Hello,

Rarely, I have seen an issue where my device will load an old value from NVM (fds_record_open()) after having previously updated the record with fds_record_update(). From my understanding, this can occur if an error occurred during the write or FDS_ERR_OPERATION_TIMEOUT occurred due to excessive BLE activity.

Question 1: When fds_record_update() updates a record and invalidates the previous entry, is it possible that a device reset (NVIC_SystemReset(), watchdog, etc) or brownout could result in two valid records in flash?

From the Nordic InfoCenter: "When you update a record, FDS actually creates a new record and invalidates the old one. This scheme ensures that data is not lost if there is a power loss in the middle of the the operation."

Source: https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/lib_fds_functionality.html?cp=9_1_3_16_1_1_1#lib_fds_functionality_update 

Ie, what happens if the device resets between the time the new record is written, and before the old record is invalidated? Seems like you would have 2 valid records on reset.

Question 2: If the answer to question 1 is "yes", then how does FDS handle this scenario? How should an application handle this scenario?

Edit:

I have a few more questions:

Question 3: Can FDS_CRC_CHECK_ON_READ and FDS_CRC_CHECK_ON_WRITE be enabled without erasing existing records?

For example, if I want to turn this feature on in a future OTA firmware update to a device already in the field?

Question 4: How should an application handle FDS_ERR_OPERATION_TIMEOUT when updating or writing a record? How does the peer manager handle this?

The only solution I know is to always keep your data structures/elements in RAM and write them to flas. If the write fails, at least the RAM copy will be up to date and you can asynchronously queue another write attempt until it succeeds. Looking at the peer manager code, it looks like it only checks for FDS_ERR_OPERATION_TIMEOUT when garbage collection fails (PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED). Why doesn't it check for this when writing bonding information to flash? Maybe it does and I am just missing it.

Thanks!

Derek

Related