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

FDS initial state

Hi, Id like to understand the FDS state after flashing the device. Im trying to check if the record exists then I use it, otherwise I write a valid info into the record. For some reason after flashing the record always exists, but obviously with some random data. How can I make sure that there is no data written in FDS?

Thanks!

image description

  • FormerMember
    0 FormerMember

    The data in flash will only be erased if you specifically do so. Re-programming chip will not erase flash.

    When using FDS, data in flash will only be erased from flash if you do a garbage collection. When deleting a record using FDS, the record itself will not immediately be deleted, but instead its record key will be set to 'zero' only. When doing garbage collection, the records with the record key 'zero' will be deleted.

  • Getting some strange result. Here is a part of main, the only place where I use fdsWrite:

    char bt[7]={0x06,0xBD,0x38,0x5B,0x48,0x91,0x20};
    		fdsWrite(SETTINGS_FILE, REC_NFC_BT_ADDRESS,bt,7);
    		fdsRead(SETTINGS_FILE, REC_NFC_BT_ADDRESS, &settingsNFCbtAddress, &len);
    		NRF_LOG_DEBUG("SETTINGS NFC BT ADDRESS (len: %d):", len);
    		NRF_LOG_HEXDUMP_INFO(settingsNFCbtAddress, len);
    		NRF_LOG_DEBUG("\r\n");
    

    and here are the functions:

        uint8_t fdsWrite(uint16_t FILE_ID, uint16_t RECORD_KEY, char * data, uint8_t dataLen)
    {
    	fds_record_t        record;
      fds_record_desc_t   record_desc;
      fds_record_chunk_t  record_chunk;
    
    // Set up data.
    record_chunk.p_data         = data;
    record_chunk.length_words   = (dataLen+4-1)/4;
    	
    	NRF_LOG_INFO("Writing FDS:");
    	NRF_LOG_HEXDUMP_INFO(record_chunk.p_data, dataLen);
    	NRF_LOG_INFO("\r\n");
    // Set up record.
    record.file_id                  = FILE_ID;
    record.key               = RECORD_KEY;
    record.data.p_chunks     = &record_chunk;
    record.data.num_chunks   = 1;
        
    ret_code_t ret = fds_record_write(&record_desc, &record);
    if (ret != FDS_SUCCESS)
    {
    	NRF_LOG_DEBUG("FDS Write ERROR: %d\r\n", ret);
    }
    
    return 0;
    }
    
    uint8_t fdsRead(uint16_t FILE_ID, uint16_t RECORD_KEY, char **data, uint8_t *dataLen)
    {
    	
    	 fds_flash_record_t  flash_record;
     fds_record_desc_t   record_desc;
     fds_find_token_t    ftok;
    	memset(&ftok, 0x00, sizeof(fds_find_token_t));
    // Loop until all records with the given key and file ID have been found.
    if (fds_record_find(FILE_ID, RECORD_KEY, &record_desc, &ftok) == FDS_SUCCESS)
    {
        if (fds_record_open(&record_desc, &flash_record) != FDS_SUCCESS)
        {
            // Handle error.
    			data = NULL;
    			*dataLen=0;
    			return 1;
        }
    		else
    		{
    			NRF_LOG_INFO("Reading FDS (len: %d):", flash_record.p_header->tl.length_words*4);
    	NRF_LOG_HEXDUMP_INFO(flash_record.p_data, flash_record.p_header->tl.length_words*4);
    	NRF_LOG_INFO("\r\n");
    			
    			*dataLen = flash_record.p_header->tl.length_words*4;
    			
    		  *data=malloc(flash_record.p_header->tl.length_words*4);
    		  memcpy(*data, flash_record.p_data, flash_record.p_header->tl.length_words*4);
    		}
        // Access the record through the flash_record structure.
        // Close the record when done.
    		
    		
        if (fds_record_close(&record_desc) != FDS_SUCCESS)
        {
            return 2;
        }
    		else  return 0;
    		
    }
    return 3;
    }
    
    
    // Simple event handler to handle errors during initialization.
    static 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)
                {
                    NRF_LOG_DEBUG("FDS Init failed\r\n");
                }
                break;
    				case FDS_EVT_GC:
        
            NRF_LOG_DEBUG("GC completed\r\n");
    				break;
            default:
                break;
        }
    }
    
    
    void fdsInit()
    {
    ret_code_t ret = fds_register(fds_evt_handler);
    if (ret != FDS_SUCCESS)
    {
        // Registering of the event handler has failed.
    }
    ret = fds_init();
    if (ret != FDS_SUCCESS)
    {
        // Handle error.
    }
    }
    

    and then the printout always shows the first BT address that I wrote in memory, but not the second one:

    0> :INFO:Writing FDS::INFO:
     0> 06 BD 38 5B 48 91 20                             ..8[H.          
     0> :INFO:
     0> :INFO:Reading FDS (len: 8)::INFO:
     0> 06 2A 51 5B 48 91 20 00                          .*Q[H. .        
     0> :INFO:
     0> APP:DEBUG:SETTINGS NFC BT ADDRESS (len: 8):APP:INFO:
     0> 06 2A 51 5B 48 91 20 00                          .*Q[H. .
    
  • Hi Kristin,

    I attached a printout from my program. It waits till FDS is initialized then it writes to a record and then it reads from it, Question is Why FDS Init callback gets called twice? Actually its called once at the first program run and after I reboot device it gets called twice. Any idea?

  • FormerMember
    0 FormerMember in reply to FormerMember

    1) then the printout always shows the first BT address that I wrote in memory, but not the second one:

    Do you mean that the printout always shows the oldest record and not the one that was newly written? If you want to update the data of a record, you should use fds_record_update(). If you write to a FILE with a given RECORD_KEY, and that file and record key already exists, there will be two records with the same record key in the same file. From what I can see in fdsRead(), it only calls fds_record_find() once, so it will only find the first instance for a given record key.

    2) How do you see that the FDS init callback gets called twice?

  • Thanks Kristen, first question is clear. For the second one you can see lines "FDS Init completed1" twice so callback was called twice?"

Related