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

Problem with fds: Flash read, write, delete calling that function using android phone.

Hello to all,

I am using nRF52832 DK with sd132, v6.0.0 and sdk 15.0.0, segger embedded studio. We want to achieve change application timer time (APP_TIMER_TICKS(update_time)) using android phone. We have a sensor devices it will wake up as per app timer time defined, we want to change this wake up time using Noridc UART tool box app. For that we are using fds example as referred in given sdk 15.0 and other nRF5-flash-storage-examples .

We are able to flash write read and delete but problem is:

  1.  When i call fds_test_find_and_delete(), fds_test_write(), fds_read() whenever received command from nordic UART app it not able to read and write at this time.
  2. I want to change update_time variable of app timer ticks using android phone and store this time in flash. Whenever want to user need to change this time first delete previous and update latest send time. 
  3. Will you please provide me program snippet for How i call flash fds API through android phone and store received time in that app_timer ticks. Confused regarding this.

I am currently using this following functions for FDS read, write, and delete:

static ret_code_t fds_test_write(void)
{
		
    //static uint32_t const m_deadbeef[2] = {0xDEADBEEF,0xBAADF00D};
    static uint8_t const m_deadbeef[1] = {0x14};
//    memcpy(m_deadbeef, write_data, sizeof(m_deadbeef));
    fds_record_t        record;
    fds_record_desc_t   record_desc;

    // Set up data.
    
    // Set up record.
    record.file_id        = FILE_ID_FDS_TEST;
    record.key            = REC_KEY_FDS_TEST;
    record.data.p_data    = &m_deadbeef;
    //record.data.length_words   = sizeof(m_deadbeef)/sizeof(uint32_t);
    record.data.length_words   = sizeof(m_deadbeef)/sizeof(uint8_t);
                    
    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)
{

    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;
    uint8_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_FDS_TEST, REC_KEY_FDS_TEST, &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;
                    data = (uint8_t *) flash_record.p_data;
                    for (uint8_t i=0;i<flash_record.p_header->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)
{
    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_FDS_TEST, REC_KEY_FDS_TEST, &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;
}

  • Hi Edvin,

    Sorry for very late reply, we have released our product.

    Will you please help me with below issue:

    Let's say in my device flash stored some data in 8 files. I want to delete this file once command received from mobile app with connected.

    Here is my below function for deleting files while app connected:

    ret_code_t fds_delete_file(uint16_t file_ID) {
      ret_code_t ret = fds_file_delete(file_ID);
      wait_for_next_write(); /* wait for this stored file successfully deleted*/
      if (ret != FDS_SUCCESS) {
        return ret;
      }
      /* Call garbage collector to clean dummpy data from flash*/
      ret = fds_gc(); 
      if (ret != FDS_SUCCESS) {
        return ret;
      }
      return NRF_SUCCESS;
    }
    
    void wait_for_next_write(void) {
      while (!fds_write_success) {
        idle_state_handle();
      }
      fds_write_success = false;
    }

    But now problem getting when i connect device and send command to call this function it will continuous waiting for fds_evt_handler(); 

    But fds_evt_handler(); is not generated. If I comment to wait_for_next_write() function that time fds event getting but got success response before flash clean.

    I want to get success response once flash data successfully deleted with ble connected with app.

    Looking forward your response..!!!

    Thanks.

  • Are you waiting for the fds_write_success after you deleted a record? Wouldn't that give the FDS_EVT_DEL_RECORD event, which will set m_fds_delete_success = true? At least if you haven't changed anything since the snippets that you sent 7 months ago.

  • I am waiting for the FDS_EVT_DEL_RECORD OR FDS_EVT_DEL_FILE but nothing get only when connected with BLE activity.

    Is this any priority issue?

    Here is my below updated functions:

    void 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.
        }
        m_fds_init_success = true;
        break;
      case FDS_EVT_WRITE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash Write event generated");
          fds_write_success = true;
        }
        fds_allocation_for_write(0);
        break;
      case FDS_EVT_DEL_RECORD:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data record deleted");
          fds_delete_success = true;
        }
        break;
      case FDS_EVT_DEL_FILE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data File deleted");
          fds_delete_success = true;
        }
        break;
      case FDS_EVT_UPDATE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data updated");
          fds_write_success = true;
        }
        fds_allocation_for_write(0);
        break;
      case FDS_EVT_GC:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Garbage Collection completed");
        }
        break;
      default:
        break;
      }
    }
    
    void wait_for_next_delete(void) {
      while (!fds_delete_success) {
        idle_state_handle();
      }
      fds_delete_success = false;
    }

  • Ok. so two issues, then:

    1: fds_file_delete() will trigger the FDS_EVT_DEL_RECORD event, which will set fds_delete_success = true. You are waiting for the fds_write_success to become true. It never will.

    2: In your fds_delete_file(). If one of the function calls inside here returns ret != NRF_SUCCESS, your FDS operations aren't queued. 

    So let us say that inside fds_delete_files() returns e.g. FDS_ERR_NO_SPACE_IN_QUEUES, then fds_delete_file() returns FDS_ERR_NO_SPACE_IN_QUEUE, but your delete operation is not queued, and you will never get the FDS_EVT_DEL_RECORD (or the FDS_EVT_WRITE, for that matter. See issue 1.)

    However, you wait for this event (the wrong one) before you check the return value of fds_file_delete();

    You should check the return value before you wait for the event. Something like this:

    ret_code_t fds_delete_file(uint16_t file_ID)
    {
        ret_code_t ret = fds_file_delete(file_ID);
        if (ret != FDS_SUCCESS)
        {
            return ret;
        }
        wait_for_next_delete(); // PLEASE NOTE THIS CHANGE. not wait_for_next_write()
        ...
    }

Related