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;
}

  • Try the attached project with SDK15.2.0 (download here).

    I used the Keil IDE, so if you want to use something else, e.g. Segger Embedded Studio, please add the files:

    fds.c

    nrf_fstorage.c

    nrf_fstorage_sd.c

    ble_app_uart_fds.zip

    Best regards,

    Edvin

  • Hi Edvin,

    I am not test my current project with new sdk due not having much time.

    So i have modify my fds_write function as like bellow:

    static ret_code_t fds_write(uint16_t file_ID, uint16_t rec_key) {
      NRF_LOG_INFO("In flashing: %s", (uint32_t)fds_write_buff);
      ret_code_t err_code;
      fds_record_t record;
      fds_record_desc_t record_desc;
      fds_find_token_t ftoken;
      memset(&ftoken, 0x00, sizeof(fds_find_token_t));
      // Set up record.
      record.file_id = file_ID;
      record.key = rec_key;
      record.data.p_data = &fds_write_buff;
      record.data.length_words = (sizeof(fds_write_buff) + 3) / 4; //sizeof(m_deadbeef)/sizeof(uint8_t);
    
      if (fds_record_find(file_ID, rec_key, &record_desc, &ftoken) == FDS_SUCCESS) {
        err_code = fds_record_update(&record_desc, &record);
        APP_ERROR_CHECK(err_code);
      }
      else
      {
        err_code = fds_record_write(&record_desc, &record);
        APP_ERROR_CHECK(err_code);
      }
      return NRF_SUCCESS;
    }

    In this function got another issue which is:

    When i erase complete chip and flash my program then using android phone call command and store required config. in flash this is worked.

    Now after when i connect phone read flash data is correct and that same time i call command to update flash data updated event got. but not get this data.

    When i disconnect BLE connection and call update flash data then got correct data. Means i am trying to say before send command flash data update first disconnect and connect again then send this command That way got flash config. data. 

    Another problem is if i set flag on each write & update record data event for wait that time BLE is hang not worked another functionality need to reset. So i removed wait flash in my fds_write function.

    Will you please tell me why this happen, If i disconnect BLE connection and connect then send flash update command to device that time flash data successfully updated and also got updated flash data.

    Waiting for your response.. 

    Thanks....!!

  • I meant that you could test the project I attached to see how to do it, not port your current project.

    Are you waiting for the udate or write event BEFORE you read the data from flash again?

    vishal said:
    Another problem is if i set flag on each write & update record data event for wait that time BLE is hang not worked another functionality need to reset. So i removed wait flash in my fds_write function.

     How do you wait in your application?

  • Thanks for quick response,

    Here is bellow wait for update or write event:

    static ret_code_t fds_write(uint16_t file_ID, uint16_t rec_key) {
      NRF_LOG_INFO("In flashing: %s", (uint32_t)fds_write_buff);
      ret_code_t err_code;
      fds_record_t record;
      fds_record_desc_t record_desc;
      fds_find_token_t ftoken;
      memset(&ftoken, 0x00, sizeof(fds_find_token_t));
      // Set up record.
      record.file_id = file_ID;
      record.key = rec_key;
      record.data.p_data = &fds_write_buff;
      record.data.length_words = (sizeof(fds_write_buff) + 3) / 4; //sizeof(m_deadbeef)/sizeof(uint8_t);
    
      if (fds_record_find(file_ID, rec_key, &record_desc, &ftoken) == FDS_SUCCESS) {
        err_code = fds_record_update(&record_desc, &record);
        APP_ERROR_CHECK(err_code);
    	while(!m_fds_update_success)
        {
            // wait
        }
        m_fds_update_success = false;
      }
      else
      {
        err_code = fds_record_write(&record_desc, &record);
        APP_ERROR_CHECK(err_code);
    	while(!m_fds_write_success)
        {
            // wait
        }
        m_fds_write_success = false;
      }
      return NRF_SUCCESS;
    }

    set this flag true in fds event :

      case FDS_EVT_WRITE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          m_fds_write_success = true;
          NRF_LOG_INFO("Flash Write event generated");
        }
        break;
      case FDS_EVT_DEL_RECORD:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data record deleted");
          m_fds_delete_success = true;
        }
      case FDS_EVT_DEL_FILE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data File deleted");
        }
      case FDS_EVT_UPDATE:
        if (p_fds_evt->result == FDS_SUCCESS) {
          NRF_LOG_INFO("Flash data updated");
          m_fds_update_success = true;
        }

     How do you wait in your application?

    means this is same as above right if not can you please provide program snippet for wait in application.

    Thanks you.....

  • This seems correct, but it is not the same as in your previous reply, so I am a bit confused. 

    To the left is your last snippet, and to the right is the snippet from your previous reply:

    So did it work after you added the waiting?

Related