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

fds_stat function always says there are 4 words used before I write anything using fds

Hello, I am using nRF52 DK and softdevice s112, developing with SDK V15.2. I am exploring the fds library and have encountered some strange behavior. When I connect the nRF52 DK, erase the flash memory, and then run a simple application that calls fds_stat() and prints the number of used words, the fds_stat_t struct always reads 4 used words. This occurs when I have not written anything using fds manually. After I write a float value, fds_stat then says there are 8 words used (+4 which is expected). When I erase the flash again and restart the application, I again see 4 used words before manually writing anything myself.

I have not read anything online about fds internally allocating 4 words on initialization. I have tested this with 4 nRF52 DKs and see the same results every time. I need to know if this is normal or expected behavior, because it will be critical for my application. I also need to know if I should expect this same behavior when using the nRF52810-CAAA chip. My full application needs to turn on, check words written to flash storage, and will do two very different things if words have been written to flash or not. The device will be completely power cycled, but needs to retain information across power cycles, which is why I am using the fds library.

If there will always be 4 used words upon initialization of the fds module, then my code can be written as follows:

fds_stat_t fds_stats;
fds_init();
fds_stat(&fds_stats);

if (fds_stats.words_used > 4)
    // do something
else
    // do something completely different
    
// Continue program

If it is guaranteed that 4 words will always be used by default, then any number of used words greater than 4 means I manually wrote words using fds. However, if another chip runs the application and begins with 0 words used at initialization, the logic will break. If the initial words used is 0, then I write any amount of words less than 4, and the device is power cycled and restarted, the above if statement will go into the second branch (<4 used words) as if I have not written words manually. When in fact I have.

There of course is a more elaborate way to check to see if I have manually written words, as the file ID and record keys are constant values (per stored variable) in my application. So every power cycle, I could check to see if there are any words/records that match these file ID and record keys. However the above method is much more simple.

Any insights to this would be greatly appreciated. 

  • Wait, on second thought, +4 words after writing a float value is not expected. One word is 4-bytes, correct? This means that writing a float should mean one more word has been written to flash. Maybe something strange is going on here. Here is my full code

    static void fds_write(float test_value)
    {
        #define FILE_ID    0x1111
        #define REC_KEY    0x2222
        #define FLOAT_LEN  1
        fds_record_t       record;
        fds_record_desc_t  record_desc;
    
        // Set up record.
        record.file_id             = FILE_ID;
        record.key                 = REC_KEY;
        record.data.p_data         = &test_value;
        record.data.length_words   = FLOAT_LEN;
                        
        ret_code_t ret = fds_record_write(&record_desc, &record);
        if (ret != FDS_SUCCESS)
        {
            NRF_LOG_INFO("ERROR WRITING TO FLASH\n");
        }
        NRF_LOG_INFO("SUCCESS WRITING TO FLASH\n");
        NRF_LOG_FLUSH();
    }
    
    int main(void) {
    
        fds_stat_t fds_stats;
        float      test_num = 123.456789
        fds_init();
        fds_stat(&fds_stats);
        // This call prints "words used: 4"
        NRF_LOG_INFO("words used: %u\n", fds_stats.words_used);
        
        fds_write(test_num);
        fds_stat(&fds_stats);
        // This call prints "words used: 8"
        NRF_LOG_INFO("words used: %u\n", fds_stats.words_used);
    }

  • You are writing a full new record, whitch includes your 4 byte float value and some overhead - 12 bytes seem correct.

    Remember that FDS needs to find this new record somehow in flash later.

  • By default, you have 2 data pages, each with a 2-word page tag. The record header adds 3 words (12 bytes) to each record.

Related