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

How to write, read and store uint8_t data_array via FDS

Hello everybody,

I used SDK14.2.0 , S132 .

I keep the data from nus_data in the uint8_t array. Then I am trying to write the array with use fds_write.

My fds_write function;

static ret_code_t kls_fds_write(uint32_t file_id, uint32_t record_key , uint8_t write_data[])
{		
	fds_record_t        record;
	fds_record_desc_t   record_desc;
	
	// Set up record.
	record.file_id           = file_id;
	record.key               = record_key;
	record.data.p_data       = &write_data;
	record.data.length_words = (sizeof(write_data) + 3) / 4;     //sizeof(write_data);   //(sizeof(write_data) + 3) / sizeof(uint32_t);
	
	ret_code_t rc;
	rc = fds_record_write(&record_desc, &record);
	if (rc != FDS_SUCCESS)
	{
			/* Handle error. */
			NRF_LOG_INFO("FDS Write Handle error.");
			return rc;
	}
	NRF_LOG_INFO("Writing Record ID = %d \r\n",record_desc.record_id);
	return NRF_SUCCESS;
	
}

I use my fds_write function by this way;

static void save_data( uint8_t *p_data)
{
	NRF_LOG_INFO("save_data");
	uint8_t source_data_0[10] ;		
	
	// assign source datas  ********************************	
	for (uint32_t i = 0; i < 10; i++)				
	{
		source_data_0[i] = p_data[i];
	}
	while (flag_write_fds == false);
	kls_fds_write(FILE_ID, RECORD_KEY, source_data_0);
	
	NRF_LOG_HEXDUMP_INFO(source_data_0, sizeof(source_data_0));
	
	allow_advertisement = false;

}

Then I am trying to read and store the data into another array.

My fds_read function;

static ret_code_t kls_fds_read(uint32_t file_id, uint32_t relevant_record_key , uint8_t read_data[])
{	
		fds_flash_record_t  flash_record;
		fds_record_desc_t   record_desc;
		fds_find_token_t    ftok;
		fds_record_t        record;
		/* It is required to zero the token before first use. */
		memset(&ftok, 0x00, sizeof(fds_find_token_t));
		
		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, relevant_record_key, &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);
				
				uint8_t * pointer_to_record_data;
				pointer_to_record_data = (uint8_t *)record.data.p_data; 
				
				if(flash_record.p_header->record_key == relevant_record_key)
				{
					for(uint8_t i = 0; i < 10; i++)
					{
							read_data[i] = *pointer_to_record_data;
							pointer_to_record_data++;
					}
				}
				
				NRF_LOG_INFO("Data = ");
				NRF_LOG_HEXDUMP_INFO(read_data, sizeof(read_data));
				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;		
}

I use my fds_read function by this way;

static void first_Setup(void)
{
    NRF_LOG_INFO("first_Setup Start");
    uint8_t dest_data_0[10]  = {0};
	
    while (flag_write_fds == 0);
    kls_fds_read(FILE_ID, RECORD_KEY, dest_data_0);
    	
    NRF_LOG_INFO("dest_data_0 : ");
    NRF_LOG_HEXDUMP_INFO(dest_data_0, 10);
    
}

I can write and read something but these are not meaningful data. Or I can not read the data I wrote because of anything. I obviously could not figure out exactly where the problem was.

The steps I want to take are as follows;

  • Store particular nus_data into an array (uint8_t source_data_0[10] ) -> I'm already doing this. No problem.
  • Write the stored array(uint8_t source_data_0[10] ) via FDS -> I do that already, but I do not know exactly whether it is successful.
  • Read the stored array(uint8_t source_data_0[10] )via FDS and Store the read array(source_data_0[10] ) in another array (uint8_t dest_data_0[10]  = {0}).

Test Result;

I sent the nus data( "aaaaaaaaaa" ) and I can store it into source_data_0[] successfully. Then I use my fds_write function;

0> <info> app: save_data
0> <info> app: Writing Record ID = 1
0>
0> <info> app: 61 61 61 61 61 61 61 61|aaaaaaaa
0> <info> app: 61 61 |aa

Finally I tried to read and result is;

0> <info> app: first_Setup Start

0> <info> app: Start searching...
0>
0> <info> app: Found Record ID = 1
0>
0> <info> app: Data =
0> <info> app: 00 04 00 20 |...
0> <info> app:
0>
0> <info> app: dest_data_0 :
0> <info> app: 00 04 00 20 E9 08 00 00|... é...
0> <info> app: 7D 05 |}.

As a result; The data I read is not the same as the data I write . May be I read it in the wrong format, I do not know exactly. 

So, Do you have any suggestion ?

  • Tried another experiment;

    uint32_t *data ;
    
    data = (uint32_t *) flash_record.p_data;
    NRF_LOG_HEXDUMP_INFO(data, sizeof(data));

    I write ;

    0> <info> app: 41 30 31 31 30 30 30 34|A0110004
    0> <info> app: 30 00 |0.

    Result;

     0> <info> app:  31 97 00 00            |1—..  

  • Another Experiment;

    uint32_t *data ;
    				
    data = (uint32_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]);
    }

    I wrote;

    0> <info> app: 41 30 31 31 30 30 30 34|A0110004
    0> <info> app: 30 00 |0.

    Result;

    0> <info> app: 0x 9731
    0> <info> app: 0x20005CB0
    0> <info> app: 0x20005CD0
    0> <info> app: 0x 971B

  • Hey Ugur,

    I spoke in error earlier when I said that the record descriptor was not used. It is clearly used in:
    while (fds_record_find(file_id, relevant_record_key, &record_desc, &ftok) == FDS_SUCCESS)

    I believe it's the way you are accessing the fds_flash_record_t flash_record afterwords.

    uint32_t your_data[8] = {0};
    uint8_t your_byte = 0;
    
    for(uint8_t i = 0; i < flash_record->p_header.length_words; i++){
        your_data[i] = flash_record->p_data[0];
    }
    
    your_byte = (uint8_t)your_data[0];

  • Hi haakonsh thanks for answer but unfortunately I got an error like this ;
    "..\..\..\main.c(387): error:  #44: expression must have pointer type"

    Also the missing part is: I want to write and read an array of 10 members, not just a one byte element. If I can not save it all in one go, I need to define something like a buffer. I used pstorage at sdk 8 and it worked very well. But I can not migrate to FDS.

    I did this in SDK 8 as well;

    static void pstorage_save(uint8_t * p_data)
    {
    		pstorage_handle_t       handle;
    		pstorage_handle_t		block_3_handle;
    		pstorage_module_param_t param;
    		uint8_t                 source_data_3[16] = {'\0'};		
    		uint32_t                retval;
    		
    		retval = pstorage_init();
    		if(retval != NRF_SUCCESS){
    				bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
    		}
    	     
    		param.block_size  = 16;                   //Select block size of 16 bytes
    		param.block_count = 53;                    //Select 32 blocks, total of 512 bytes
    		param.cb          = example_cb_handler;   //Set the pstorage callback handler
    			
    		retval = pstorage_register(&param, &handle);
    		if (retval != NRF_SUCCESS){
    				bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
    		}
    		
    //		//Get block identifiers
    		pstorage_block_identifier_get(&handle, 3, &block_3_handle);
    
    // CLEAR ************************		 
    		//Clear 16 bytes, starting from block 3
    		pstorage_wait_handle = block_3_handle.block_id;            //Specify which pstorage handle to wait for
    		pstorage_wait_flag = 1;
    		pstorage_clear(&block_3_handle, 16);  
    		while(pstorage_wait_flag) { power_manage(); }              //Sleep until clear operation is finished.		
    // CLEAR ************************			
    
    // assign source datas  ********************************	
    		for (uint32_t i = 0; i < 6; i++)				
    		{
    			source_data_3[i] = p_data[i];
    		}
    // ******************************************************		
    		// STORE DATA
    		pstorage_wait_handle = block_3_handle.block_id;            //Specify which pstorage handle to wait for
    		pstorage_wait_flag = 1;                                    //Set the wait flag. Cleared in the example_cb_handler
    		pstorage_store(&block_3_handle, source_data_3, 16, 0);     //Write to flash, only one block is allowed for each pstorage_store command
    		if(retval != NRF_SUCCESS)
    		{
    				bsp_indication_set(BSP_INDICATE_RCV_ERROR);
    		}
    		while(pstorage_wait_flag) { power_manage(); }              //Sleep until store operation is finished.
    }

    I then entered any uint8_t some_array[] instead of p_data and it was done in SDK 8. But now I can not reach the data I write with FDS. What I want is actually very simple, but I guess I can not tell because my English is weak.

  • purgoufr said:
    "..\..\..\main.c(387): error:  #44: expression must have pointer type"

    Can you share the relevant code, I do not know what you are referring to.

    The record you want to write needs only a pointer to an address in memory and the length in words(4bytes). You can store as many words in your record as long as you comply with the following requirement:

    length_in_words + FDS_HEADER_SIZE >= FDS_PAGE_SIZE - FDS_PAGE_TAG_SIZE

    They way a C compiler accesses a given element in an array is to use the address of the initial element 0 and add the size of the array type multiplied by the element's index number.

    Say an uint32_t my_array[5]; is located at address 0x2000B000:

    If you want to access element 3 of my_array the compiler will take the address of element 0(0x2000B000) and add 3 * size_of(uint32_t) = 0x2000B000 +  0xC = 0x2000B00C. 

    This means that you can access any array's elements as long as you have the starting address and the type size. 

    // accesing the 3rd element of an array. 
    
    uint32_t my_array[5] = {0x00, 0x01, 0x02, 0x03, 0x04};
    
    // Referencing the the array:
    uint32_t * p_array = &my_array; // p_array = address of element 0 of my_array
    
    // Dereferencing the pointer that points to the array:
    uint32_t data = *p_array[3];

Related