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

NRF51, SDK 12, FDS Issue(s)

Hello,

I am not able to make the FDS work. Here is my setup

  • NRF51
  • SDK 12.3
  • S130 (2.0.1), i.e. s130_nrf51_2.0.1_softdevice.hex
  • Using peer manager as well

sdk_config.h:

// <e> FDS_ENABLED - fds - Flash data storage module
//==========================================================
#ifndef FDS_ENABLED
#define FDS_ENABLED 1
#endif
#if  FDS_ENABLED
// <o> FDS_OP_QUEUE_SIZE - Size of the internal queue. 
#ifndef FDS_OP_QUEUE_SIZE
#define FDS_OP_QUEUE_SIZE 5
#endif

// <o> FDS_CHUNK_QUEUE_SIZE - Determines how many @ref fds_record_chunk_t structures can be buffered at any time. 
#ifndef FDS_CHUNK_QUEUE_SIZE
#define FDS_CHUNK_QUEUE_SIZE 8
#endif

// <o> FDS_MAX_USERS - Maximum number of callbacks that can be registered. 
#ifndef FDS_MAX_USERS
#define FDS_MAX_USERS 4
#endif

// <o> FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. 
// <i> One of the virtual pages is reserved by the system for garbage collection.
// <i> Therefore, the minimum is two virtual pages: one page to store data and
// <i> one page to be used by the system for garbage collection. The total amount
// <i> of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES
// <i> @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes.

#ifndef FDS_VIRTUAL_PAGES
#define FDS_VIRTUAL_PAGES 3
#endif

// <o> FDS_VIRTUAL_PAGE_SIZE  - The size of a virtual page of flash memory, expressed in number of 4-byte words.
 

// <i> By default, a virtual page is the same size as a physical page.
// <i> The size of a virtual page must be a multiple of the size of a physical page.
// <256=> 256 
// <512=> 512 
// <1024=> 1024 

#ifndef FDS_VIRTUAL_PAGE_SIZE
#define FDS_VIRTUAL_PAGE_SIZE 256
#endif

#endif //FDS_ENABLED
// </e>

// <e> FSTORAGE_ENABLED - fstorage - Flash storage module
//==========================================================
#ifndef FSTORAGE_ENABLED
#define FSTORAGE_ENABLED 1
#endif
#if  FSTORAGE_ENABLED
// <o> FS_QUEUE_SIZE - Configures the size of the internal queue. 
// <i> Increase this if there are many users, or if it is likely that many
// <i> operation will be queued at once without waiting for the previous operations
// <i> to complete. In general, increase the queue size if you frequently receive
// <i> @ref FS_ERR_QUEUE_FULL errors when calling @ref fs_store or @ref fs_erase.

#ifndef FS_QUEUE_SIZE
#define FS_QUEUE_SIZE 4
#endif

// <o> FS_OP_MAX_RETRIES - Number attempts to execute an operation if the SoftDevice fails. 
// <i> Increase this value if events return the @ref FS_ERR_OPERATION_TIMEOUT
// <i> error often. The SoftDevice may fail to schedule flash access due to high BLE activity.

#ifndef FS_OP_MAX_RETRIES
#define FS_OP_MAX_RETRIES 3
#endif

// <o> FS_MAX_WRITE_SIZE_WORDS - Maximum number of words to be written to flash in a single operation. 
// <i> Tweaking this value can increase the chances of the SoftDevice being
// <i> able to fit flash operations in between radio activity. This value is bound by the
// <i> maximum number of words which the SoftDevice can write to flash in a single call to
// <i> @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs.

#ifndef FS_MAX_WRITE_SIZE_WORDS
#define FS_MAX_WRITE_SIZE_WORDS 256
#endif

#endif //FSTORAGE_ENABLED
// </e>

Using basically this example in our application.

What happens:

  • Writing doesn't return any error
  • However FDS callback is never triggered!
  • When trying to read, getting error FDS_ERR_NOT_FOUND when using fds_record_find(). Weird as write, didn't return any error.

As far as I have searched, I have seen some related topics, but not a single answer. E.g.:

Any clues? Any debug-direction? Thanks!

EDIT 1:

After doing some debugging my self this what is happening:

FDS:

  • queue_process() is called
  • which calls write_execute()
  • which calls record_header_write_begin(), which returns 0x00 (=FDS_OP_EXECUTING or FDS_SUCCESS)
  • I see the next step is: p_op->write.step = FDS_OP_WRITE_RECORD_ID;, but is never executed! Probably because queue_process(result); is never called, because fs_event_handler() in fds.c is never called. But why?

EDIT 2:

I just run the example, just the main.c with SDK 12.3 and it has the exact same behavior...!

  • I managed to figure this out. It was the result of two things:

    • The fs_sys_event_handler() of the fstorage was not called in the sys_evt_dispatch() (some legacy code of ours was interfering).
    • The RTTdubug print was too slow. We added delays to allow RTT to have the chance of sending the prints. (Even better is to use breakpoints in this case)

    As to why the example was also showing the same behavior (which was super confusing to us), it has to do probably with the RTT prints. We didn't have the time to check it this out, but my guess is it works just fine.

  • I think I have the first issue of the fstorage, how did you resolve this? I'm using SDK 12.3 with the nRF51.

    When I run my code I initialize fstorage and do a test erase, write and read. This works.

    Then I put the device in sleep (sd_app_evt_wait) after this I do not get a fs_sys_event_handler trigger.

    Could you help me?

Related