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

Controller hangs with call to fds_init()

I'm using nrf52 with SDK version 12.0.0. I'm trying to use the FDS for my application. I used one of the existing fds example from link fds_example.

With this example, I call the function "fds_test_init" which in turn calls "fds_init". After debugging, I reached to a point where the function "sd_flash_write" is called and this function declaration is taken from the place "/nRF5SDK/components/softdevice/s132/headers/nrf_soc.h".

It is at the call of this function that the controller hangs with message "Starting target cpu" in the console window.

Below is the definitions of FS & FDS macros:

  • FS_QUEUE_SIZE = 4
  • FS_OP_MAX_RETRIES = 3
  • FS_MAX_WRITE_SIZE_WORDS = 1024
  • FDS_OP_QUEUE_SIZE = 4
  • FDS_CHUNK_QUEUE_SIZE = 8
  • FDS_MAX_USERS = 3
  • FDS_VIRTUAL_PAGES = 3
  • FDS_VIRTUAL_PAGE_SIZE = 2048

Could anyone support me here to understand why the controller hangs at the call of the function "sd_flash_write"?

Thanks in advance.

  • This example is for SDK 11. I recommend to get it to work with that SDK first, before porting it to SDK 12.

  • Hello Petter Myhre, Thanks for the reply. Even if the example works for SDK11, my goal to get it working for SDK12. Hence, could you please let me know if there is an example available for SDK12?

  • I understand, I just meant that maybe you could learn something from getting it to work on SDK 11 first, before porting it to SDK 12. I'm not aware of and FDS example for SDK 12, but I think there should be one in SDK 13. I don't really understand what you mean by "Starting target cpu" in the console window. What example are you using as a starting point? Maybe you can edit your question and upload your complete project so I can test it here? What SoftDevice are you using?

  • Here is the code:

    #include "RT-RTE.h"
    #include "RT_OSWrapper.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "fds.h"
    
    static volatile uint8_t write_flag = 0;
    
    static void my_fds_evt_handler(fds_evt_t const * const p_fds_evt)
    {
        switch (p_fds_evt->id)
        {
            case FDS_EVT_INIT:
                if (p_fds_evt->result != FDS_SUCCESS)
                {
                    // Initialization failed.
                }
                break;
                case FDS_EVT_WRITE:
                      if (p_fds_evt->result == FDS_SUCCESS)
                      {
                         write_flag = 1;
                      }
                      break;
            default:
                break;
        }
    }
    static ret_code_t fds_test_write(void)
    {
          #define FILE_ID     0x1111
          #define REC_KEY     0x2222
          static uint32_t const m_deadbeef[2] = {0xDEADBEEF,0xBAADF00D};
          fds_record_t        record;
          fds_record_desc_t   record_desc;
          fds_record_chunk_t  record_chunk;
          // Set up data.
          record_chunk.p_data         = m_deadbeef;
          record_chunk.length_words   = 2;
          // Set up record.
          record.file_id              = FILE_ID;
          record.key                    = REC_KEY;
          record.data.p_chunks       = &record_chunk;
          record.data.num_chunks   = 1;
    
          ret_code_t ret = fds_record_write(&record_desc, &record);
          if (ret != FDS_SUCCESS)
          {
                return ret;
          }
           NRF_LOG_INFO("Writing Record ID = %d \r\n",record_desc.record_id);
          return NRF_SUCCESS;
    }
    
    static ret_code_t fds_read(void)
    {
          #define FILE_ID     0x1111
          #define REC_KEY     0x2222
          fds_flash_record_t  flash_record;
          fds_record_desc_t   record_desc;
          fds_find_token_t    ftok ={0};//Important, make sure you zero init the ftok token
          uint32_t *data;
          uint32_t err_code;
    
          NRF_LOG_INFO("Start searching... \r\n");
          // Loop until all records with the given key and file ID have been found.
          while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)
          {
                err_code = fds_record_open(&record_desc, &flash_record);
                if ( err_code != FDS_SUCCESS)
                {
                   return err_code;
                }
    
                NRF_LOG_INFO("Found Record ID = %d\r\n",record_desc.record_id);
                NRF_LOG_INFO("Data = ");
                data = (uint32_t *) flash_record.p_data;
                for (uint8_t i=0;i<flash_record.p_header->tl.length_words;i++)
                {
                   NRF_LOG_INFO("0x%8x ",data[i]);
                }
                NRF_LOG_INFO("\r\n");
                // Access the record through the flash_record structure.
                // Close the record when done.
                err_code = fds_record_close(&record_desc);
                if (err_code != FDS_SUCCESS)
                {
                   return err_code;
                }
          }
          return NRF_SUCCESS;
    
    }
    
    
    static ret_code_t fds_test_find_and_delete (void)
    {
       #define FILE_ID     0x1111
          #define REC_KEY     0x2222
          fds_record_desc_t   record_desc;
          fds_find_token_t    ftok;
    
          ftok.page=0;
          ftok.p_addr=NULL;
          // Loop and find records with same ID and rec key and mark them as deleted.
          while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)
          {
             fds_record_delete(&record_desc);
             NRF_LOG_INFO("Deleted record ID: %d \r\n",record_desc.record_id);
          }
          // call the garbage collector to empty them, don't need to do this all the time, this is just for demonstration
          ret_code_t ret = fds_gc();
          if (ret != FDS_SUCCESS)
          {
                return ret;
          }
          return NRF_SUCCESS;
    }
    
    static ret_code_t fds_test_init (void)
    {
    
          ret_code_t ret = fds_register(my_fds_evt_handler);
          if (ret != FDS_SUCCESS)
          {
                   return ret;
    
          }
          ret = fds_init();
          if (ret != FDS_SUCCESS)
          {
                return ret;
          }
    
          return NRF_SUCCESS;
    
    }
    
    int main(void)
    {
       ret_code_t err_code;
    
       err_code = NRF_LOG_INIT(NULL);
       APP_ERROR_CHECK(err_code);
       err_code = fds_test_init();
       APP_ERROR_CHECK(err_code);
       err_code = fds_test_find_and_delete();
       APP_ERROR_CHECK(err_code);
       err_code =fds_test_write();
       APP_ERROR_CHECK(err_code);
       //wait until the write is finished.
       while (write_flag==0);
       fds_read();
    
    }
    

    I'm using s132 as the SoftDevice. I will look into the SDK13 for FDS example.

  • The example should be used with a SoftDevice, I tested your code, and it runs to while (write_flag==0);, but write_flag never becomes 1, because you haven't enabled the SoftDevice.

    From the documentation of sd_flash_write() you can see that it has different behavior depending if the SoftDevice is enabled or not:

    If the SoftDevice is enabled:
    This call initiates the flash access command, and its completion will be communicated to the
    application with exactly one of the following events:
        - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
        - @ref NRF_EVT_FLASH_OPERATION_ERROR   - The command could not be started.
    
    If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the write has been completed.
    
Related