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

FDS_ERR_NOT_FOUND issue of yps_storage_find in sdk 14.0.1

Hello,

I implemented overall flow related with FDS function including garbage collection, when I check garbage collection, it is ok, it confirm that the data will be saved with writing or updating function in event handler, please refer the following codes, (refer to FDS_EVT_GC in the log)

but I have one problem, FDS_ERR_NOT_FOUND error is sometimes happened with yps_storage_find, when I check the flow of codes, it is happened in yps_storage_write & yps_storage_read function, so I can't read the data at that time,

I can't know the reason, I repeatedly tried to delete record before writing data, so it should be done as to fds_record_write function, is it right ?

please help to let me know the reason and what it is wrong, thankful for your support in advance,

thanks.

Error log :

Event: FDS_EVT_DEL_RECORD received (FDS_SUCCESS) 
Deleted record ID: 242 0x0
yps_storage_find not found 0x1111 0x3333
Event: FDS_EVT_WRITE received (FDS_SUCCESS) 
fds_record_write : 0 243 
yps_password = 159 
Uncalibrated time:	01/01/18 - 15:26:40
Calibrated time:	01/01/18 - 15:26:40
DelEvent: FDS_EVT_DEL_RECORD received (FDS_SUCCESS) 
eted record ID: 243 0x0
yps_storage_find not found 0x1111 0x3333
Event: FDS_EVT_WRITE received (FDS_SUCCESS) 
fds_record_write : 0 244 
yps_password = 160 
Uncalibrated time:	01/01/18 - 15:26:41
Calibrated time:	01/01/18 - 15:26:41
Event: FDS_EVT_DEL_RECORD received (FDS_SUCCESS) 
Deleted record ID: 244 0x0
yps_storage_find not found 0x1111 0x3333
fds_record_write : 0 245 
yps_storage_read not found 0xEvent: FDS_EVT_WRITE received (FDS_SUCCESS) 
1111 0x3333
yps_password = 160 
Uncalibrated time:	01/01/18 - 15:26:42
Calibrated time:	01/01/18 - 15:26:42
Event: FDS_EVT_DEL_RECORD received (FDS_SUCCESS) 
Deleted record ID: 245 0x0
yps_storage_find not found 0x1111 0x3333
Event: FDS_EVT_WRITE received (FDS_SUCCESS) 
fds_record_write : 0 246 
yps_password = 162 
Uncalibrated time:	01/01/18 - 15:26:43
Calibrated time:	01/01/18 - 15:26:43
Event: FDS_EVT_DEL_RECORD received (FDS_SUCCESS) 

firstly, in the main routine,

if(password[0] == 250)
	password[0] = 0;
	
password[0]++;

yps_storage_password_delete();
					
err_code = yps_storage_password_write(password);
APP_ERROR_CHECK(err_code);

uint8_t yps_password[YPS_PASSWORD_LENGTH];
err_code = yps_storage_password_read(yps_password);	    
APP_ERROR_CHECK(err_code);
printf("yps_password = %d \r\n", yps_password[0]);

_1ms_count = 0;	

and then each functions of FDS,

#include <string.h>
#include "hal_fds_module.h"
#include "fds.h"
#include "app_error.h"
#include "app_util.h"
#include "app_util_bds.h"

//#pragma pack(push, 4)
//
//struct schedule_db_schema {
//	uint8_t day;
//	uint8_t hour;
//	uint8_t minute;
//};
//static struct schedule_db_schema db_schema;// __ALIGN(4);
//#pragma pack(pop)
 
static volatile bool 		m_fds_evt_init = false;
static volatile bool 		m_pending_write  = false;      /**< Flag used to preserve write request during Garbage Collector activity. */
static volatile bool 		m_pending_update = false;      /**< Flag used to preserve update request during Garbage Collector activity. */

static uint16_t	       		m_pending_msg_key    = 0;//love_0124
static uint32_t        		m_pending_msg_size   = 0;    /**< Pending write/update request data size. */
static uint8_t const * 		m_p_pending_msg_buff = NULL; /**< Pending write/update request data pointer. */

static fds_record_desc_t  	record_desc;            /**< Record descriptor. */
static fds_record_t       	rec;                 /**< Record description used for writes. */

/* Array to map FDS return values to strings. */
char const * fds_err_str[] =
{
    "FDS_SUCCESS",
    "FDS_ERR_OPERATION_TIMEOUT",
    "FDS_ERR_NOT_INITIALIZED",
    "FDS_ERR_UNALIGNED_ADDR",
    "FDS_ERR_INVALID_ARG",
    "FDS_ERR_NULL_ARG",
    "FDS_ERR_NO_OPEN_RECORDS",
    "FDS_ERR_NO_SPACE_IN_FLASH",
    "FDS_ERR_NO_SPACE_IN_QUEUES",
    "FDS_ERR_RECORD_TOO_LARGE",
    "FDS_ERR_NOT_FOUND",
    "FDS_ERR_NO_PAGES",
    "FDS_ERR_USER_LIMIT_REACHED",
    "FDS_ERR_CRC_CHECK_FAILED",
    "FDS_ERR_BUSY",
    "FDS_ERR_INTERNAL",
};

/* Array to map FDS events to strings. */
static char const * fds_evt_str[] =
{
    "FDS_EVT_INIT",
    "FDS_EVT_WRITE",
    "FDS_EVT_UPDATE",//love_0124 Event for fds_record_update.
    "FDS_EVT_DEL_RECORD",//love_0124 Event for fds_record_delete.
    "FDS_EVT_DEL_FILE",
    "FDS_EVT_GC",
};

/**
 * @brief   Prepare record structure for write or update request.
 *
 * @details Configures file ID, record KEY, data to be written and message length.
 *
 * @param[in] buff  Pointer to the YPS message to be stored in FLASH.
 * @param[in] size  Size of YPS message.
 */
static void yps_file_prepare_record(uint16_t key, uint8_t const * p_buff, uint32_t size)
{
	// Set up record.
	rec.file_id           = FILE_ID;
	rec.key               = key;
	rec.data.p_data       = p_buff;
	rec.data.length_words = BYTES_TO_WORDS(size); // Align data length to 4 bytes.
}

static void yps_storage_fds_evt_handler(fds_evt_t const * const p_fds_evt)
{
	ret_code_t ret;
		
	printf("Event: %s received (%s) \r\n", fds_evt_str[p_fds_evt->id], fds_err_str[p_fds_evt->result]);
                  	
	switch (p_fds_evt->id)
	{
		case FDS_EVT_INIT:
//			printf("FDS_EVT_INIT %x\r\n", p_fds_evt->result);
			
			if (p_fds_evt->result != FDS_SUCCESS)
				printf("FDS_EVT_INIT Initialization failed\r\n");
			else
				m_fds_evt_init = true;
		break;
		case FDS_EVT_WRITE:
//			printf("FDS_EVT_WRITE %x\r\n", p_fds_evt->result);
//			
//			if (p_fds_evt->result == FDS_SUCCESS)
//				printf("FDS_EVT_WRITE FDS_SUCCESS\r\n");
//			else 
//				printf("FDS_EVT_WRITE Failed!!!\r\n");
		break;
		
		case FDS_EVT_UPDATE:
//			printf("FDS_EVT_UPDATE %x\r\n",p_fds_evt->result);
		break;
		case FDS_EVT_DEL_RECORD:
//			printf("FDS_EVT_DEL_RECORD %x\r\n", p_fds_evt->result);
//			ret = fds_gc();
//			APP_ERROR_CHECK(ret);
		break;
		case FDS_EVT_DEL_FILE:
//			printf("FDS_EVT_DEL_FILE %x\r\n",p_fds_evt->result);
		break;
		case FDS_EVT_GC:
			//Perform pending write/update.
			if (m_pending_write)
			{
				printf("FDS_EVT_GC m_pending_write %x\r\n", p_fds_evt->result);
				m_pending_write = false;
				// Prepare record structure.
				yps_file_prepare_record(m_pending_msg_key, m_p_pending_msg_buff, m_pending_msg_size);				
				ret = fds_record_write(&record_desc, &rec);
				printf("FDS_EVT_GC fds_record_write : %x %d \r\n", ret, record_desc.record_id);
				APP_ERROR_CHECK(ret);
			}
			else if (m_pending_update)
			{
				printf("FDS_EVT_GC m_pending_update %x\r\n", p_fds_evt->result);				
				m_pending_update = false;
				// Prepare record structure.
				yps_file_prepare_record(m_pending_msg_key, m_p_pending_msg_buff, m_pending_msg_size);				
				ret = fds_record_update(&record_desc, &rec);
				printf("FDS_EVT_GC fds_record_update : %x %d \r\n", ret, record_desc.record_id);				
				APP_ERROR_CHECK(ret);
			}
		
		break;
		
		default:
		break;
	}
}

ret_code_t yps_storage_init(void) {
	
	ret_code_t ret = fds_register(yps_storage_fds_evt_handler);

	if (ret != FDS_SUCCESS) {
		return ret;
	}

	ret = fds_init();

	if (ret != FDS_SUCCESS) {
		return ret;
	}

	fds_stat_t stat = {0};
	
	ret = fds_stat(&stat);//love_0123
	APP_ERROR_CHECK(ret);
    
	return NRF_SUCCESS;
}

bool yps_storage_find(uint16_t file_id, uint16_t key, fds_record_desc_t * p_desc) {
	
	ret_code_t ret;
	fds_find_token_t ftok;
	
	memset(&ftok, 0, sizeof(fds_find_token_t));
	
	ret = fds_record_find(file_id, key, p_desc, &ftok);
//	APP_ERROR_CHECK(ret);
	
	if (ret == FDS_SUCCESS) {
		printf("fds_record_find Record ID = %d\r\n", p_desc->record_id);
		return true;
	}

	printf("yps_storage_find not found 0x%x 0x%x\r\n", file_id, key);

	return false;
}

ret_code_t yps_storage_write(uint16_t file_id, uint16_t key, uint8_t const * p_data, uint16_t length_bytes) {
	
	ret_code_t ret;
//	fds_record_desc_t record_desc;
//	
//	memset(&record_desc, 0, sizeof(record_desc));

//	fds_record_t const rec =
//	{
//		.file_id           = file_id,
//		.key               = key,
//		.data.p_data       = &p_data,
//		.data.length_words = 1//BYTES_TO_WORDS(length_bytes)
//	};

	// Prepare record structure.
	yps_file_prepare_record(key, p_data, length_bytes);
	
	if(yps_storage_find(file_id, key, &record_desc)) 
	{
		// update
		ret = fds_record_update(&record_desc, &rec);
		printf("fds_record_update : %x %d \r\n", ret, record_desc.record_id);
		
		if (ret == FDS_ERR_NO_SPACE_IN_FLASH)//love_0124
		{
		        // If there is no space, preserve write request and call Garbage Collector.
		        m_pending_update     = true;
		        m_pending_msg_key    = key;//love_0124
		        m_pending_msg_size   = length_bytes;
		        m_p_pending_msg_buff = p_data;

			ret = fds_gc();
			APP_ERROR_CHECK(ret);
		}
	} 
	else 
	{
		// new
		ret = fds_record_write(&record_desc, &rec);
		printf("fds_record_write : %x %d \r\n", ret, record_desc.record_id);

		if (ret == FDS_ERR_NO_SPACE_IN_FLASH)//love_0124
		{
			// If there is no space, preserve update request and call Garbage Collector.
		        m_pending_write      = true;
		        m_pending_msg_key    = key;//love_0124		        
		        m_pending_msg_size   = length_bytes;
		        m_p_pending_msg_buff = p_data;
			
			ret = fds_gc();
			APP_ERROR_CHECK(ret);
		}
	}

	return ret;
}

ret_code_t yps_storage_read(uint16_t file_id, uint16_t key, uint8_t * p_data) {
	
	ret_code_t ret;
	fds_flash_record_t  	flash_record = {0};
	fds_find_token_t 	ftok = {0};

//	memset(&ftok, 0x00, sizeof(fds_find_token_t));
		
	ret = fds_record_find(file_id, key, &record_desc, &ftok);
//	APP_ERROR_CHECK(ret);
	
	if(ret != FDS_SUCCESS)
	{
		printf("yps_storage_read not found 0x%x 0x%x\r\n", file_id, key);
		return ret;
	}
	
	ret = fds_record_open(&record_desc, &flash_record);
	APP_ERROR_CHECK(ret);
	
	if (ret != FDS_SUCCESS)
		return ret;
	// Access the record through the flash_record structure.
	memcpy(p_data, flash_record.p_data, (flash_record.p_header->length_words * sizeof(uint32_t)));//sizeof(uint32_t) BYTES_PER_WORD
	
	// Close the record when done.
	ret = fds_record_close(&record_desc);
	APP_ERROR_CHECK(ret);
	
	if (ret != FDS_SUCCESS)
		return ret;

	return ret;
}

ret_code_t yps_storage_find_and_delete(uint16_t file_id, uint16_t key)
{
	ret_code_t ret;
//	fds_record_desc_t record_desc;
	fds_find_token_t ftok;
	
//	memset(&record_desc, 0, sizeof(fds_record_desc_t));	
	memset(&ftok, 0, sizeof(fds_find_token_t));
	
	// Loop and find records with same ID and rec key and mark them as deleted.
	while (fds_record_find(file_id, key, &record_desc, &ftok) == FDS_SUCCESS)
	{
		ret = fds_record_delete(&record_desc);
		printf("Deleted record ID: %d 0x%x\r\n", record_desc.record_id, (unsigned int) ret);
	}

//	// call the garbage collector to empty them, don't need to do this all the time, this is just for demonstration
//	ret = fds_gc();
//
//	if (ret != FDS_SUCCESS)
//	{
//		return ret;
//	}

	return NRF_SUCCESS;
}

ret_code_t yps_storage_id_write(uint8_t * p_id) {
	return yps_storage_write(FILE_ID, REC_KEY_ID, p_id, YPS_ID_LENGTH);
}

ret_code_t yps_storage_password_write(uint8_t * p_password) {
	return yps_storage_write(FILE_ID, REC_KEY_PASSWORD, p_password, YPS_PASSWORD_LENGTH);
}

ret_code_t yps_storage_id_read(uint8_t * p_id) {
	ret_code_t ret = yps_storage_read(FILE_ID, REC_KEY_ID, p_id);
	return ret;
}

ret_code_t yps_storage_password_read(uint8_t * p_password) {
	ret_code_t ret = yps_storage_read(FILE_ID, REC_KEY_PASSWORD, p_password);
	return ret;
}

ret_code_t yps_storage_id_delete(void) {
	return yps_storage_find_and_delete(FILE_ID, REC_KEY_ID);
}

ret_code_t yps_storage_password_delete(void) {
	return yps_storage_find_and_delete(FILE_ID, REC_KEY_PASSWORD);
}

bool get_fds_evt_init(void) {
	return m_fds_evt_init;
}
  • I don't quite understand what the problem is. Do you not expect to get FDS_ERR_NOT_FOUND after you have deleted the record? Could you please clarify what the problem is?

  • Hi, Petter,

    firstly, thankful for rapid response, I worried that the error is happened in the timing of read trial, even though fds_record_find function return the error, what I mean is that when I would like to read the stored data(by fds_record_write funtion), the stored data can't be normally print out by yps_storage_read function, you can see the log,

    yps_storage_find not found 0x1111 0x3333

    fds_record_write : 0 245

    yps_storage_read not found 0xEvent: FDS_EVT_WRITE received (FDS_SUCCESS)

    first line is different from third line, I wonder why the error is happened in yps_storage_read function, the timing is that fds_record_write was already done, anyway as a result, I can't read the stored data when I would like to check it, it is a problem,

    please help to let me know whether it is really a problem or not kindly,

    thankful for your support in advance,

    ref) Should I check the completion as to writing in event handler ? and then I should try to read the stored data, is it right ? Please help to let me know good idea,

    thanks.

  • Yes, you should wait for the FDS_EVT_WRITE event in the handler before assuming that the record is written. Before you get the event, you don't know if the record has been written or not.

  • according to your description, if the data is stored in the communication flow (by handler) of BLE, this kind of issue can't be happened in most cases, currently I test by instant writing and reading, so this issue can be happened, is it right ? I wonder whether I should check the completion of writing in normal usage(ble communication), thankful for your kindness in advance, thanks.

  • You should always wait for the completion event before assuming that the operation is complete. Always.

Related