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

How store large amount data 73Kbytes into flash using FDS?

We are using nRF52840 with sdk 15.0 version & segger embedded studio. We are able to store some small amount of configuration data into flash using FDS. But now we want to store large data array near about 73Kbytes into flash. I am writing example code for storing this data and created one dummy array of size 73728 bytes. But I getting following ERROR:

FDS_ERR_RECORD_TOO_LARGE

I am confused for configuration of FDS for storing 73Kbytes 

Here is bellow edited in sdk_config.h

FDS_VIRTUAL_PAGES 10

FDS_VIRTUAL_PAGE_SIZE 2048

FDS_OP_QUEUE_SIZE 4

Will you please help me how i use this above configuration for storing 73KB data. & how i fixed FDS_ERR_RECORD_TOO_LARGE ERROR?

Is it possible to store this data in one fds_record_write (...) call request?

Thanks in advanced..!!

  • Hi,

    Now i am able to store 73Kbytes data into flash with sending multiple request up to 19 pages. I have changed rec key every request let say first request reckey is 1 then it 2, 3, 4.. etc. 

    But now problem getting when i want to retrieve this stored data for all this pages.  First of kec key 1 & 2 got data but when i send read request with 3 reckey that time my application is crash. Nothing say any error but when i debugging it get __aeabi_memcpy4 when this bellow function reached:

    fds_find_token_t ftok;
    memset(&ftok, 0x00, sizeof(fds_find_token_t)); 

    Will you please help me how i read this stored data from flash with proper way?

    Thanks

  • Hey,

    I tried to do the same thing myself and I was able to read and write 10 records.

    This is my "app_fds.c" file. This implements the write and read functions. In write function, the same array is getting written 10 times. The file_id is same in all cases but the rec_id changes.

    #include "fds.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /**************************Private Function Definitions**************************/
    
    uint32_t file_id = 0x01000;
    uint32_t rec_id = 0x1111;
    
    /* Data to write in flash. */
    struct 
    {
      char string[100];                         //Change this size as required.
    }fds_data;
    
    /* A record containing dummy configuration data. */
    fds_record_t record =
    {
      .file_id           = 0x00,
      .key               = 0x00,
      .data.p_data       = &fds_data,
      /* The length of a record is always expressed in 4-byte units (words). */
      .data.length_words = 25,                  //Also change this if array size is changed.
    };
    
    /* Flag to check fds initialization. */
    static bool volatile m_fds_initialized = false;;
    static bool volatile m_fds_write = false;
    static bool volatile m_gc_complete = false;
    
    
    /**
    * @brief             Event handler for FDS events
    * @param[in]         p_evt              Structure with FDS data
    * @retval            NONE
    */
    static void fds_evt_handler(fds_evt_t const * p_evt)
    {
      /*NRF_LOG_INFO("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)
          {
            m_fds_write = true;
          }
        } break;
        
      case FDS_EVT_DEL_RECORD:
        {
          if (p_evt->result == FDS_SUCCESS)
          {
            NRF_LOG_INFO("Record ID:\t0x%04x",  p_evt->del.record_id);
            NRF_LOG_INFO("File ID:\t0x%04x",    p_evt->del.file_id);
            NRF_LOG_INFO("Record key:\t0x%04x", p_evt->del.record_key);
          }
          ///m_delete_all.pending = false;
        } break;
        
      case FDS_EVT_GC:
        {
          NRF_LOG_INFO("GC Done");
          m_gc_complete = true;
        }break;
        
      default:
        break;
      }
    }
    /**
    * @brief             Function to go to low power when waiting for FDS
    * @param[in]         NONE
    * @retval            NONE
    */
    static void power_manage(void)
    {
    #ifdef SOFTDEVICE_PRESENT
      (void) sd_app_evt_wait();
    #else
      __WFE();
    #endif
    }
    
    /**
    * @brief             The FDS takes some time for init. Waiting till it gets initialised properly.
    * @param[in]         NONE
    * @retval            NONE
    */
    static void wait_for_fds_ready(void)
    {
      while (!m_fds_initialized)
      {
        power_manage();
      }
    }
    
    static void wait_for_write(void)
    {
      while (!m_fds_write)
      {
        power_manage();
      }
      m_fds_write = false;
    }
    
    
    void fds_write()
    {
      ret_code_t rc;
      fds_record_desc_t desc = {0};
      record.file_id = file_id;
    
      for(int i=0;i<10;i++)
      {  
        memset(&desc, 0x00, sizeof(fds_record_desc_t)); 
        record.key = rec_id;
        rc = fds_record_write(&desc, &record);
        wait_for_write();
        if(rc == FDS_SUCCESS) {
          NRF_LOG_INFO("Data written with id %d",rec_id);
        }
        else {
          NRF_LOG_INFO("Write Failed, id %d",rc);
        }
        rec_id++;
      }  
      rec_id = 0x1111;
    }
    
    void fds_read()
    {
      NRF_LOG_INFO("Starting Read");
      ret_code_t rc;
      
      fds_record_desc_t desc = {0};
      fds_find_token_t  tok  = {0};
      
      for(int i=0;i<10;i++)
      {
        memset(&desc, 0x00, sizeof(fds_record_desc_t)); 
        memset(&tok, 0x00, sizeof(fds_find_token_t)); 
        
        rc = fds_record_find(file_id, rec_id, &desc, &tok);
      
        if (rc == FDS_SUCCESS)
        {
          fds_flash_record_t config = {0};
          
          /* Open the record and read its contents. */
          rc = fds_record_open(&desc, &config);
          APP_ERROR_CHECK(rc);
    
          NRF_LOG_INFO("File Found with id %d",rec_id);
          
          /* Close the record when done reading. */
          rc = fds_record_close(&desc);
          APP_ERROR_CHECK(rc);
        }
        rec_id++;
      }
    }
    
    /**
    * @brief             Initialise FDS
    * @param[in]         NONE
    * @retval            NONE
    */
    void init_fds()
    {
      ret_code_t rc;
      
      /* Register first to receive an event when initialization is complete. */
      (void) fds_register(fds_evt_handler);
      
      NRF_LOG_INFO("Initializing fds...");
      
      rc = fds_init();
      NRF_LOG_INFO("fds init %d",rc);
      APP_ERROR_CHECK(rc);
      
      /* Wait for fds to initialize. */
      wait_for_fds_ready();
    }
    

    This is simple "main.c" file

    #include "app_fds.h"
    #include "nrf_pwr_mgmt.h"
    #include "nrf_delay.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /**************************Private Function Definitions**************************/
    
    /**
    * @brief                       Function to call the power management
    * @param[in]                   NONE
    * @retval                      NONE
    */
    void idle_state_handle()
    {
      nrf_pwr_mgmt_run();
    }
    
    /**
    * @brief             Initialise the peripherals
    * @param[in]         NONE
    * @retval            NONE
    */
    void init_peripherals()
    {  
      NRF_LOG_INIT(NULL);
      NRF_LOG_DEFAULT_BACKENDS_INIT();                                                      //Use RTT as default backend
      NRF_LOG_INFO("Start\r\n");
      
      init_fds();
    }
    
    /**
    * @brief             Main Function
    * @param[in]         NONE
    * @retval            NONE
    */
    int main()
    {
      init_peripherals();
      fds_write();
      fds_read();
      
      while(1)
      {
        NRF_LOG_PROCESS();
        idle_state_handle();
      }
    }
    
    

    In "sdk_config.h"

    FDS_VIRTUAL_PAGES 11
    
    FDS_VIRTUAL_PAGE_SIZE 2048

    I don't know if this is the best way to do this, but it has worked for me.

  • Thanks Ashisk,

    Now we are able to store 74 KB data in flash also read this data, but got one issue for wait_for_write(); function. My program is not work when mobile application is connected wit device that time want to write data into flash. Because it continuous on this loop not triggering FDS_EVT_WRITE event, since this flash is not true. This happening only when BLE is connected to phone. If phone is not connected then is working and also trigger FDS event. 

    We still stuck here why this happening with BLE connection established and still it connected that time only FDS write event is not trigger.

    Thanks..

Related