This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

fstorage error issue with sdk 14.1.0

Hello,

I would like to use fstorage function, but when using the example of sdk 14.1.0, I had some errors, please help to let me know what problem is and how to define the start address, end_addr address....

     * last page of flash available to write data. */
    .start_addr = 0x0007F000, // by 0x800000
    .end_addr   = 0x000FF000,

I don't know which address I can use in the memory map(512 kb), I refer the following memory map, and I use the command to check memory (data) : nrfjprog --memrd 0x0007f000 --n 0x100

infocenter.nordicsemi.com/index.jsp

thankful for your support in advance, thanks.

Error : C:\working_dir\yps-202n\nRF5_SDK_14.1.0_1dda907\examples\ble_peripheral\ble_app_uart\hal_flash_module.c, 137 16 ==> 16 means NRF_ERROR_INVALID_ADDR

Error : C:\working_dir\yps-202n\nRF5_SDK_14.1.0_1dda907\examples\ble_peripheral\ble_app_uart\hal_flash_module.c, 145 9 ==> 9 means NRF_ERROR_INVALID_LENGTH

#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#include "nrf.h"
#include "nrf_soc.h"
#include "nordic_common.h"
#include "boards.h"
#include "app_timer.h"
#include "app_util.h"
#include "nrf_fstorage.h"

#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_fstorage_sd.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define FLASHWRITE_EXAMPLE_MAX_STRING_LEN       (62u)
#define FLASHWRITE_EXAMPLE_BLOCK_VALID          (0xA55A5AA5)
#define FLASHWRITE_EXAMPLE_BLOCK_INVALID        (0xA55A0000)
#define FLASHWRITE_EXAMPLE_BLOCK_NOT_INIT       (0xFFFFFFFF)

//love_1211
//refer to infocenter.nordicsemi.com/index.jsp

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
{
	if (p_evt->result != NRF_SUCCESS)
	{
		printf("--> Event received: ERROR while executing an fstorage operation. \r\n");
		return;
	}
	
	switch (p_evt->id)
	{
		case NRF_FSTORAGE_EVT_WRITE_RESULT:
		{
			printf("--> Event received: wrote %d bytes at address 0x%x. \r\n",
			 p_evt->len, p_evt->addr);
		} break;
		
		case NRF_FSTORAGE_EVT_ERASE_RESULT:
		{
			printf("--> Event received: erased %d page from address 0x%x. \r\n",
			 p_evt->len, p_evt->addr);
		} break;
		
		default:
		break;
	}
}

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
     * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
     * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
     * last page of flash available to write data. */
    .start_addr = 0x0007F000, // by 0x800000
    .end_addr   = 0x000FF000,
};


/* Dummy data to write to flash. */
static uint32_t 	m_data          = 0xBADC0FFE;//0xBADC0FFE;
//static char     	m_hello_world[] = "hello world";

/**@brief   Helper function to obtain the last address on the last page of the on-chip flash that
 *          can be used to write user data.
 */
static uint32_t nrf5_flash_end_addr_get()
{
    uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
    uint32_t const page_sz         = NRF_FICR->CODEPAGESIZE;
    uint32_t const code_sz         = NRF_FICR->CODESIZE;

    return (bootloader_addr != 0xFFFFFFFF ?
            bootloader_addr : (code_sz * page_sz));
}

static void print_flash_info(nrf_fstorage_t * p_fstorage)
{
    printf("========| flash info |========\r\n");
    printf("erase unit: \t%d bytes\r\n",      p_fstorage->p_flash_info->erase_unit);
    printf("program unit: \t%d bytes\r\n",    p_fstorage->p_flash_info->program_unit);
    printf("==============================\r\n");
}

void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {

    }
}

void flash_test(void)
{//nrfjprog --memrd 0x0007F000 --n 0x70  nrfjprog --memrd 0x10000010 --n 0x10
	ret_code_t rc;
	
	nrf_fstorage_api_t * p_fs_api;
	static uint32_t pages_to_erase = 1;
	
	NRF_LOG_INFO("SoftDevice is present.");
	NRF_LOG_INFO("Initializing nrf_fstorage_sd implementation...");
	/* Initialize an fstorage instance using the nrf_fstorage_sd backend.
	* nrf_fstorage_sd uses the SoftDevice to write to flash. This implementation can safely be
	* used whenever there is a SoftDevice, regardless of its status (enabled/disabled). */
	p_fs_api = &nrf_fstorage_sd;
	
	rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
	APP_ERROR_CHECK(rc);
	
	print_flash_info(&fstorage);
	
	/* It is possible to set the start and end addresses of an fstorage instance at runtime.
	* They can be set multiple times, should it be needed. The helper function below can
	* be used to determine the last address on the last page of flash memory available to
	* store data. */
	(void) nrf5_flash_end_addr_get();
	
	//    static uint32_t pages_to_erase = 1;
	rc = nrf_fstorage_erase(
		&fstorage,   /* The instance to use. */
		fstorage.start_addr,     /* The address of the flash pages to erase. */
		pages_to_erase, /* The number of pages to erase. */
		NULL            /* Optional parameter, backend-dependent. */
	);
	APP_ERROR_CHECK(rc);

	wait_for_flash_ready(&fstorage);
	NRF_LOG_INFO("Done.");
    
	/* Let's write to flash. */
//	NRF_LOG_INFO("Writing \"%x\" to flash.", m_data);
	rc = nrf_fstorage_write(&fstorage, fstorage.start_addr, &m_data, 4, NULL);
	APP_ERROR_CHECK(rc);
	
	wait_for_flash_ready(&fstorage);
	NRF_LOG_INFO("Done.");
//	
//	m_data = 0xABCDEABC;//0xDEADBEEF;
//	
////	NRF_LOG_INFO("Writing \"%x\" to flash.", m_data);
//	
//	rc = nrf_fstorage_write(&fstorage, 0x3e200, &m_data, sizeof(m_data), NULL);
//	APP_ERROR_CHECK(rc);
//	
//	wait_for_flash_ready(&fstorage);
//	NRF_LOG_INFO("Done.");
//	
////	NRF_LOG_INFO("Writing \"%s\" to flash.", m_hello_world);
//	rc = nrf_fstorage_write(&fstorage, 0x3f000, m_hello_world, sizeof(m_hello_world), NULL);
//	APP_ERROR_CHECK(rc);
//	
//	wait_for_flash_ready(&fstorage);
//	NRF_LOG_INFO("Done.");
                   
}
  • if using the original example, it can write the data in 0x3e000 ~ 0x3f000. but it can't try to erase the data, and if using the same example in my code(adding DFU, more custom service), write/erase function can't be normally worked, why...? please help to let me know the root cause,

    thanks.

  • Hi,

    Please see the figure in this link. It is correct that the end address on the last page of the flash is 0x80000 on the nRF52832, but if you have added DFU/bootloader to your code, the bootloader, MBR and bootloader settings page will be located at the end of flash here. In the code you posted, you are using 0x0007F000 - 0x000FF000, this is the bootloader settings page if you have added the bootloader and cannot be used for application data.

    About erasing, what does the nrf_fstorage_erase() function return when you try to erase ?

    Note: "nrf_fstorage_sd" calls are queued until they are done and will cause the queue to fill up if you issue too many calls in a short window of time. Erase operations are by far the slowest and can take 10s of milliseconds to complete. Whenever you perform an fstorage call you should verify that the there was room in the queue before progressing. If there was not enough room the application should wait before retrying.

  • Hello, Sigurd,

    I arrange current situation in detail, please refer the following link,

    devzone.nordicsemi.com/.../

    and there is a question : if using fds module, the user data can be preserved after doing dfu, is it right ? the data is stored in app data region of memory map.... where is located(saved) the data in memory map ? is app data ? I would like to preserve the user data after doing dfu, if so, need to use app data ? is it right ? please help to let me know the method...

    thanks.

  • Yes, to preserve application data during a DFU you need to use DFU_APP_DATA_RESERVED . See this page. I will close this post, and we can continue the discussion in your other post.

Related