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

fds_record_update sometimes always returns FDS_ERR_NO_SPACE_IN_FLASH

Hi,

I'm using FDS instead of pstorage. FDS version is SDK13.0.0. fds_record_update sometimes always returns FDS_ERR_NO_SPACE_IN_FLASH though I call fds_gc after it gets FDS_ERR_NO_SPACE_IN_FLASH every time.

static void fds_evt_handler(fds_evt_t const * const p_fds_evt)
{
    if (p_fds_evt->result != FDS_SUCCESS) {
        NRF_LOG_RAW_INFO("FDS_FAILURE %d\r\n", p_fds_evt->result);
        return;
    }

    switch (p_fds_evt->id)
    {
        case FDS_EVT_INIT:
            NRF_LOG_RAW_INFO("FDS_EVT_INIT\r\n");
            m_fstorage_operating = false;
            break;
        case FDS_EVT_WRITE:
            NRF_LOG_RAW_INFO("FDS_EVT_WRITE\r\n");
            m_fstorage_operating = false;
            break;
        case FDS_EVT_UPDATE:
            NRF_LOG_RAW_INFO("FDS_EVT_UPDATE\r\n");
            m_fstorage_operating = false;
            break;
        case FDS_EVT_DEL_RECORD:
           NRF_LOG_RAW_INFO("FDS_EVT_DEL_RECORD\r\n");
            m_fstorage_operating = false;
            break; 
        case FDS_EVT_DEL_FILE:
            NRF_LOG_RAW_INFO("FDS_EVT_DEL_FILE\r\n");
            m_fstorage_operating = false;
            break;
        case FDS_EVT_GC:
            NRF_LOG_RAW_INFO("FDS_EVT_GC\r\n");
            m_fstorage_operating = false;
        default:
            break;
    }
    NRF_LOG_FLUSH();

}

void sf_fstorage_garbage_collection()
{
    ret_code_t ret;
    m_fstorage_operating = true;

    NRF_LOG_RAW_INFO("sf_fstorage_garbage_collection\r\n");
    ret = fds_gc();
    if (ret != FDS_SUCCESS) {
        NRF_LOG_RAW_INFO("fds_gc error ret %d \r\n", ret);
    }

    while(m_fstorage_operating) {
        uint32_t err_code = sd_app_evt_wait();
        app_sched_execute();
        APP_ERROR_CHECK(err_code);
    }
    NRF_LOG_RAW_INFO("fds_gc success \r\n");
    NRF_LOG_FLUSH();
}

static void sf_print_fds_stat()
{
    fds_stat_t p_stat;
    fds_stat(&p_stat);
    _print_info("open_records   : %d\r\n", p_stat.open_records);
    _print_info("valid_records:    %d\r\n", p_stat.valid_records);
    _print_info("dirty_records:    %d\r\n", p_stat.dirty_records);
    _print_info("words_reserved: %d\r\n", p_stat.words_reserved);
    _print_info("words_used      : %d\r\n", p_stat.words_used);
    _print_info("largest_contig   : %d\r\n", p_stat.largest_contig);
    _print_info("freeable_words  : %d\r\n", p_stat.freeable_words);
}

void update_data(void)
{
  ret_code_t ret = fds_record_update(p_record_desc, &record);
  NRF_LOG_RAW_INFO("update already exist record. %d \r\n", p_record_desc->record_id);
    sf_print_fds_stat();
  while(ret == FDS_ERR_NO_SPACE_IN_FLASH)
  {
        NRF_LOG_RAW_INFO("RUN GARBAGE COLLECTION\r\n");
        sf_fstorage_garbage_collection();
          sf_print_fds_stat();
        m_fstorage_operating = true;
        ret = fds_record_update(p_record_desc, &record);
          sf_print_fds_stat();
   }
}

It makes sense to get the error every time, but it gets the error sometimes. Do you know the cause?

[2017/11/16 0:15] add sf_print_fds_stat() function. attach log file.FDS_GC_ERROR3_REPRODUCED.log

Best Regards, Haruki

  • Ok, I don't erase the complete flash every time, but only repeat update_data() using fds_record_update().

    If it gets the error every time after system reset once it gets the error, it makes sense because the cause may be that flash is full. But it gets the error sometimes, so I wonder whether the flash is really full or not.

    Peer Manager only store one user, so it is not the reason I think.

  • I found the function to retrieve file system statistic in SDK13.0.0. And I print the statistics after fds_record_update() or fds_gc() is completed, then I found that the largest_contig become not enough to store my data. I think this is fragmentation. How can I avoid this fragmentation?

  • Great! I guess it was there, just not mentioned in the documentation. I'm not sure what you mean by fragmentation. Do you want to increase the number of flash pages used by Fstorage? You can increase FDS_VIRTUAL_PAGES in sdk_config.h

  • Please see here about fragmentation.

    I set FDS_VIRTUAL_PAGES to 3 and FDS_VIRTUAL_PAGE_SIZE to 1024. So I prepare 2048 words size for FDS. I store 11 data of 4 sizes as below.

    1.(12(header)+ 576) * 7 →147 words*7

    2.(12 + 144) * 1 → 39 words

    3.(12 + 691) * 2 →176 words

    4.(12 + 774) * 1 →197 words

    And peer manager stores 26 words for 1 peer.

    Simply thinking, 2048 words size enough for my data and 1 peer. However, fds_gc() seems not to compact flash memory, that is, not to resolve fragmentation, largest_contig variable can become not enough size to store my data and 1 peer.

    So I think it is important to set FDS_VIRTUAL_PAGES to store 197 words certainly. I have to store 12 data including peer information, then the size shown below is must be enough, isn't it?

    147 words*7 + 39 words + 176 words + 26 words + 197 words * 12

    What do you think?

  • And one more question.

    Peer manager stores 26 words as you answered in this thread .

    I checked how many records peer manager uses for 1 peer information using fds_stat().

    I guess peer manager uses 2 records for 1 peer information, 26 words. Am I correct? If so, i have to change 197 words * 12 to 197 words * 13.

Related