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

What is the best method for utilizing all of the flash for data storage

The overall goal and then the specifics of what's been tried: I'm trying to utilize as much of the left-over flash space as possible to store environmental data during periods of non-connectivity with a Bluetooth hub. I'm running into issues of incomplete writes and occasional faults that appear to be due to timing issues while performing write and erase operations.

Scenario: I'm working on an nRF51 device with 256kB of flash space. The SDK 12.3 is in use with v2.0.1 of the S130 SoftDevice. The device acts as a peripheral and there is only one master connection at a time. The connection is maintained for long durations while the master device is in range and the connection is dropped when page erase operations have to be performed. I'm using around 100 pages right now to store unaligned samples across words but staying within pages. The last four pages are left unused although I believe only one is needed by the peer manager for bonding information. I'm also leaving two pages of buffer space from the end of the application, but for no particular reason at the moment. Calls to write and erase can happen asynchronously as they are kicked off by both internally timed events and Bluetooth events caused by hub interactions.

What's in use right now: I'm currently using the S130 functions, sd_flash_write() and sd_flash_page_erase(). I was originally using the NVMC functions from the peripheral drivers, namely nrf_nvmc_page_erase and nrf_nvmc_write_bytes(), etc. I had to stop using the NVMC functions because of timing issues during both Bluetooth connections and while advertising. The writes would work 99% of the time as far as I could tell but the erases failed every time because of the 20ms halts being caused by the flash operation. The sd_flash_write and sd_flash_erase operations work some of the time. They always return NRF_SUCCESS but do not always seem to complete their operations. I tried using the event getter, sd_evt_get(), but this doesn't seem to generate any events. I didn't see any requirement to register an event handler and the call is used to poll for an event, not respond to a callback, at least as far as the documentation states.

With the requirement to use as much of the left-over space as possible, it looks like the FDS is not an option. But maybe it is and I'm misunderstanding how the space allocation works. fstorage might be an option but it's not clear if I can control the page allocation enough to get as much space as I'd like. I haven't tried the flash manager either. Are the SoftDevice functions the right place to be handling the flash read and write operations? Or is the FDS, flash manager, or fstorage the safer and more correct way to access the flash while still doing bluetooth operations?

  • If you haven't modified anything, typically three pages are reserved by FDS (for Peer Manager).

    If the SoftDevice is enabled you should use sd_flash_write() and sd_flash_page_erase() (if you are not using FDS).

    sd_flash_write() and sd_flash_page_erase() returning success doesn't mean that the flash operation was successful, as you can see from the documentation of these functions you have you wait for the NRF_EVT_FLASH_OPERATION_SUCCESS event. This is typically received in sys_evt_dispatch() registered with softdevice_sys_evt_handler_set().

    I would recommend to try to use FDS. You can configure how many pages it should use. You will share these pages with Peer Manager.

  • While we haven't found a definitive solution, the interim fix right now is to stick with the sd_flash_X() functions with an added nrf_delay to increase the odds of getting a successful callback before moving on. We're successfully using the remaining flash space from the first page after our application to the 4th-to-last page. The FDS is currently initialized to use 3 pages based on sdk_config.h (FDS_VIRTUAL_PAGES). 10 to 22 ms delays for writes and 50 ms delays for erases have gotten rid of any issues as far as our tests have gone. We're going to look into the real space usage by the FDS on individual virtual pages and try implementing the same system within that framework. I don't know if that's a real "answer" to this so I'll leave it open for a bit to see if anyone else has more experience with the flash storage library usage and maximising the available space within the operational constraints.

Related