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

FDS Data Corrupted

Hello, Nordic Forum!

I've been developing a wrapper library that uses the FDS to store my application data. I have 3 type of data to store: an array of 14 uint16_t, an array of 14 uint32_t and a structure made of a float, and a uin8_t. I use a single file and one key per data type.

What I did to work around the asynchronicity of the FDS library was to develop a queue of operations (this can be Write or Delete), and a flag system that allows the library to know in what state it is (free, deleting, writing/updating and collecting garbage). When a function is called, the library checks the state, if is busy, the operation is queued, if is available is performed right away. The transitions between states and the popping of the queue element are performed through the FDS event handler.

My problem is that the reading doesn't work well. When I write, everything seems fine. I print the data using HEXDUMP and the values are consistent, but when I read, on average, half the values are OK, and the other half are not. For example, 7 of the 14 values in the array, match the values I wrote, and the rest are 0, but sometimes, only 4 of the values are OK and the rest are 0.

This are the functions I use to read/write in memory:

static ret_code_t _storage_fds_record_exists(storage_key_t key,
                                             fds_record_desc_t *p_record_desc) {
  fds_find_token_t ftok = {0};

  return fds_record_find(STORAGE_FILE_ID, key, p_record_desc, &ftok);
}

static ret_code_t _storage_fds_write(storage_key_t key, void *p_data,
                                     uint16_t length_words) {
  NRF_LOG_DEBUG("_storage_fds_write\n");
  fds_record_t record = {0};
  fds_record_desc_t record_desc = {0};
  fds_record_chunk_t record_chunk = {0};

  record_chunk.p_data = p_data;
  record_chunk.length_words = length_words;

  record.file_id = STORAGE_FILE_ID;
  record.key = key;
  record.data.p_chunks = &record_chunk;
  record.data.num_chunks = 1;

  ret_code_t err_code = _storage_fds_record_exists(key, &record_desc);

  if (err_code == NRF_SUCCESS) {
    NRF_LOG_DEBUG("Record Exist\n");
    err_code = fds_record_update(&record_desc, &record);
  } else if (err_code == FDS_ERR_NOT_FOUND) {
    NRF_LOG_DEBUG("Record Does Not Exist\n");
    err_code = fds_record_write(&record_desc, &record);
  } else {
    NRF_LOG_ERROR("_storage_fds_record_exists fail: %d\n", err_code);
    return err_code;
  }

  if (err_code != FDS_SUCCESS) {
    if (err_code == FDS_ERR_NO_SPACE_IN_FLASH) {
      NRF_LOG_DEBUG("No Space in Flash\n");
    } else {
      NRF_LOG_ERROR("fds_record_write fail: %d\n", err_code);
    }
    return err_code;
  }

  return NRF_SUCCESS;
}

static ret_code_t _storage_fds_read(storage_key_t key, void *p_data,
                                    uint16_t data_length) {
  ret_code_t err_code;
  fds_flash_record_t flash_record = {0};
  fds_record_desc_t record_desc = {0};
  fds_find_token_t ftok = {0};

  err_code = fds_record_find(STORAGE_FILE_ID, key, &record_desc, &ftok);

  if (err_code != FDS_SUCCESS) {
    if (err_code != FDS_ERR_NOT_FOUND) {
      NRF_LOG_ERROR("fds_record_find fail\n", err_code);
    }
    return err_code;
  }

  err_code = fds_record_open(&record_desc, &flash_record);

  if (err_code != FDS_SUCCESS) {
    NRF_LOG_ERROR("fds_record_open fail: %d\n", err_code);
    return err_code;
  }

  memcpy(p_data, flash_record.p_data, data_length);

  err_code = fds_record_close(&record_desc);

  if (err_code != FDS_SUCCESS) {
    NRF_LOG_ERROR("fds_record_close fail: %d\n", err_code);
    return err_code;
  }

  return NRF_SUCCESS;
}

Here's a screenshot of the terminal when I write the memory:

Writing

And when I read:

Reading

Sorry for the long post, and thanks in advance.

Related