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

nrf_fstorage_erase returns invalid address error

Hello,

I've been working on the ble_multilink example and managed to combine that with the ble_hrs_c example to connect to multiple heart rate units and receive the data through UART. Instead of searching for specific pre-defined UUIDs I would like to enable the flash storage functionality so that a user can send specific UUIDs to the device, through the Android app, and store them in the flash storage. After that I would like the device to connect to the different devices which are advertising the UUIDs that have been stored in flash.

At the moment i have enabled the flash storage and can successfully store the first UUID, but when I try to store the second one an Invalid Address error is thrown when trying to erase the next storage space before writing the second UUID. Through some research online I found that this error is thrown when the data that will be written or the memory address are not word aligned. Hence I made sure both of those values are word aligned but that did not seem to fix the problem.

I'm not entirely sure what where exactly this is going wrong but I'm assuming its throwing the error here (in the nrf_fstorage.c nrf_fstorage_erase() function):

/* Address must be aligned to a page boundary. */
if (    ((page_addr & (p_fs->p_flash_info->erase_unit - 1)) != 0)
    ||  !addr_within_bounds(p_fs, page_addr, (len * p_fs->p_flash_info->erase_unit)))
{
    return NRF_ERROR_INVALID_ADDR;
}

I created separate files for all the fstorage functions for better readability and these are the fs_utils.h and fs_utils.c. The part of the code which im trying to store the data is shown here (this is the data handler for my custom service for sending data through the phone app):

extern volatile uint32_t finished_storing_uuids;														/**< Flag for determining whether all the UUIDs have been stored. */	
extern volatile uint32_t is_busy;																						/**< External global flag used for waiting for asynchronous events. */
extern volatile uint32_t search_in_flash;																		/**< Global flag used for determining whether to search in flash for the peer UUIDs. */
volatile uint32_t store_address = SENSOR_UUID_ADDRESS;											/**< Index for last address that a UUID has been stored in. */

void pcs_data_handler(ble_pcs_t * p_pcs, uint8_t const * p_data){ ret_code_t err_code;
uint16_t data_to_store = 0;
uint16_t retrieved_data = 1;

if (!is_busy)
{
	if ((p_data[0] << 8 | p_data[1]) != 0x0000)
	{
		search_in_flash = 1;
		if (store_address != FS_END_ADDRESS)
		{
			data_to_store = p_data[0] << 8 | p_data[1];
			retrieved_data = fs_read_uuid(store_address);
			if (retrieved_data != NULL)
			{
				NRF_LOG_INFO("Address to store to: %d", store_address);
				
				err_code = fs_write_uuid(store_address, data_to_store);
				APP_ERROR_CHECK(err_code);
				
				if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
				{
					NRF_LOG_ERROR("Failed storing UUID in flash. Error 0x%x. ", err_code);
				}
				else
				{
					store_address = store_address + 4;
					NRF_LOG_INFO("Address after store: %d", store_address);
				}
			}
		}
		else
		{
			NRF_LOG_ERROR("Flash storage is full");
		}
	}
	else
	{
		finished_storing_uuids = 1;
	}
}}

I'm sorry if my explanation is a bit of a mess. Please let me know if you would like more information regarding my project because I'm not sure I included all the information there.

Also I'm using a nrf52832 PCA10040 s132 dev board with SDK 14.0.0.

Related