Hello,
we are using SDK version 15.3 and mesh SDK version 3.2.0, on a nRF52840 DK board using the Segger Embedded Studio IDE version 4.52 (64-bit).
Our goal is to add Flash Data Storage (FDS) capabilities to our products firmware to store some data on nonvolatile memory on demand.
To start off, we tried the FDS example on our hardware using a freshly downloaded SDK and mesh SDK. It might be a problem with our SES configs, but we had to replace the NRF_LOG_INFO occurrences on main.c with printf's to get something on the terminal, but after that, we got to see how many boot sequences occurred since the device was flashed.
Then we got back to the light switch example and tried including everything that was needed from the flash_fds example on the examples/peripheral/flash_fds folder of the mesh SDK.
We show below a comprehensive list of changes made to the light switch example project and files, hoping to get the same behavior on the light switch example that we got on the FDS one:
1 We included fds.h to the top of main.c, declared all the functions needed for the basic working of the FDS example, and added some parts of the FDS example to main.c.
#include "fds.h" static struct { bool delete_next; //!< Delete next record. bool pending; //!< Waiting for an fds FDS_EVT_DEL_RECORD event, to delete the next record. } m_delete_all; /* Flag to check fds initialization. */ static bool volatile m_fds_initialized; static void fds_evt_handler(fds_evt_t const * p_evt) { // __LOG("Event: %s received (%s)", fds_evt_str[p_evt->id], fds_err_str[p_evt->result]); switch (p_evt->id) { case FDS_EVT_INIT: if (p_evt->result == FDS_SUCCESS) { m_fds_initialized = true; } break; case FDS_EVT_WRITE: { if (p_evt->result == FDS_SUCCESS) { // __LOG("Record ID:\t0x%04x", p_evt->write.record_id); // __LOG("File ID:\t0x%04x", p_evt->write.file_id); // __LOG("Record key:\t0x%04x", p_evt->write.record_key); } } break; case FDS_EVT_DEL_RECORD: { if (p_evt->result == FDS_SUCCESS) { // __LOG("Record ID:\t0x%04x", p_evt->del.record_id); // __LOG("File ID:\t0x%04x", p_evt->del.file_id); // __LOG("Record key:\t0x%04x", p_evt->del.record_key); } m_delete_all.pending = false; } break; default: break; } } /**@brief Sleep until an event is received. */ static void power_manage(void) { #ifdef SOFTDEVICE_PRESENT (void) sd_app_evt_wait(); #else __WFE(); #endif } /**@brief Wait for fds to initialize. */ static void wait_for_fds_ready(void) { while (!m_fds_initialized) { power_manage(); } } int main(void) { initialize(); start(); /* Register first to receive an event when initialization is complete. */ (void) fds_register(fds_evt_handler); ret_code_t rc = fds_init(); APP_ERROR_CHECK(rc); /* Wait for fds to initialize. */ wait_for_fds_ready(); fds_stat_t stat = {0}; rc = fds_stat(&stat); APP_ERROR_CHECK(rc); printf("Found %d valid records.", stat.valid_records); printf("Found %d dirty records (ready to be garbage collected).", stat.dirty_records); for (;;) { (void)sd_app_evt_wait(); } }
2 - Then we tried to compile the program and fixed all the problems the compiler had with not finding a file or function, by adding the following:
2.1 - On the project we added the to c_user_include_directories:
$(SDK_ROOT)/components/libraries/fds;
$(SDK_ROOT)/components/libraries/fstorage;
$(SDK_ROOT)/components/libraries/atomic_fifo;
$(SDK_ROOT)/components/libraries/crc16;
2.2 - We added the following files to the project:
$(SDK_ROOT)/components/libraries/atomic_fifo/nrf_atfifo.c
$(SDK_ROOT)/components/libraries/crc16/crc16.c
$(SDK_ROOT)/components/libraries/fds/fds.c
$(SDK_ROOT)/components/libraries/fstorage/nrf_fstorage.c
$(SDK_ROOT)/components/libraries/fstorage/nrf_fstorage_sd.c
3 - We searched the FDS example for all mentions on "storage" and "flash", and copied all the definitions that matched, so these were the relevant lines that were added/modified:
#ifndef FDS_ENABLED #define FDS_ENABLED 1 #endif #ifndef FDS_VIRTUAL_PAGES #define FDS_VIRTUAL_PAGES 5 #endif #ifndef FDS_VIRTUAL_PAGES_RESERVED #define FDS_VIRTUAL_PAGES_RESERVED 2 #endif #ifndef FDS_CRC_CHECK_ON_READ #define FDS_CRC_CHECK_ON_READ 1 #endif #ifndef NRF_FSTORAGE_ENABLED #define NRF_FSTORAGE_ENABLED 1 #endif
FDS_VIRTUAL_PAGES was originally set to 3, but since we are using mesh and from our nrf_mesh_config_app.h file we have
#define ACCESS_FLASH_PAGE_COUNT (1) #define DSM_FLASH_PAGE_COUNT (1)
and since we know that the FDS uses the same flash area that the DSM and ACCESS Layer stuff, we chose to add to the default 3 VIRTUAL_PAGES the 2 that the mesh stuff seem to be using.
Also, to offset the available flash area from the one used by the mesh, we also set FDS_VIRTUAL_PAGES_RESERVED to 2, where it was 0 originally.
4- We also found this resource that advised us to include the following code to nrf_mesh_config_app.h
#include "fds.h" #include "fds_internal_defs.h" #define FLASH_MANAGER_RECOVERY_PAGE_OFFSET_PAGES FDS_PHY_PAGES
After all these modifications, the light switch example could be compiled, but upon booting on debug mode, the program halted without logging any assert error.
The debugger showed the program halted on address 0xA60 of the program and that, for us, was very weird because that low on the memory stack, that is MBR region.
5- Finally we tried copying the entirety of the contents of linker_section_placement_macros and linker_section_placements_segments properties from the FDS project to the light switch example:
FDS:
linker_section_placement_macros:
FLASH_PH_START=0x0;
FLASH_PH_SIZE=0x100000;
RAM_PH_START=0x20000000;
RAM_PH_SIZE=0x40000;
FLASH_START=0x26000;
FLASH_SIZE=0xda000;
RAM_START=0x20002210;
RAM_SIZE=0x3ddf0
linker_section_placements_segments:
FLASH RX 0x0 0x100000;
RAM RWX 0x20000000 0x40000
light switch:
linker_section_placement_macros:
FLASH_PH_START=0x0;
FLASH_PH_SIZE=0xf8000;
RAM_PH_START=0x20000000;
RAM_PH_SIZE=0x3f000;
FLASH_START=0x26000;
RAM_START=0x20002da0;
linker_section_placements_segments:
FLASH RX 0x0 0xf8000;
RAM RWX 0x20000000 0x3f000
But even after the light switch project had these properties matching the ones of the FDS, the error was the same.
6- As we were desperate to solve this issue, we tried increasing both FDS_VIRTUAL_PAGES to 30 and FDS_VIRTUAL_PAGES_RESERVED to 10 so that there was not a possibility of having overlaps, the error was still the same
We suspect there might be a problem with defining memory areas, but I'm afraid we cannot proceed anymore alone and would require some help from you guys solving this issue.
For that purpose, we are adding the zipped project so you can take a look at it: light_switch.zip
Thank you in advance,
Rúben Marques