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

fstorage in chosen area

Hello, I'd like to store a large amount of data in flash and in a chosen area. As a start, I've chosen the area starting from 0x77000 and ending at 0x78000 Iv'e written this

const tGlobalData romData  __attribute__((at(0x77000))) __attribute__((used));
static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result);
FS_REGISTER_CFG(fs_config_t my_fs_config) =
    {
        .callback  = fs_evt_handler,    // Function for event callbacks.
        .num_pages = 4,                 // Number of physical flash pages required.
        .priority  = 0xFE,               // Priority for flash usage.
        .p_start_addr = (uint32_t*)0x77000,
        .p_end_addr = (uint32_t*)0x78000
    };
    
static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result)
{
    switch(evt->id)
    {
        case FS_EVT_STORE:
            if(result == FS_SUCCESS){
            }
            break;

        case FS_EVT_ERASE:
            // Handle erase event
            break;

        default:
            //Do nothing
            break;
    }
}

void initROM()
{
  //fs_ret_t ret = fs_init();
}

void saveROM()
{
  volatile fs_ret_t fs_ret;
  fs_ret= fs_erase(&my_fs_config,(uint32_t*)&romData,4,NULL);
  fs_ret= fs_store(&my_fs_config,(uint32_t*)&romData,(uint32_t*)&globalData,(sizeof(tGlobalData)+1)/4,NULL);
}

void readROM()
{
  memcpy(&globalData,&romData,sizeof(tGlobalData));
}

the erase operation fails. After debug, the start address at config is 0x7D000, so that &romData is out of range. The arear is welle allocated by the linker, so I should miss something.

  • Hi Cedric,

    Why did you comment out fs_init() ?

    I tested with this example here and able to set the start address, no problem.

  • Hello, I've comment fs_init during tries, I just forgot to uncomment before posting the code. In the example you gave, you don't control the destination address of the stored data. It's somewhere in the ROM area reserved for peer manager data and some other. I need more space, and as I have a bootloader too, I need to precisely control the ROM address of the stored data.

  • Yes, I mentioned, I modified the code and can set the start address. It worked. Code I used:

    	FS_REGISTER_CFG(fs_config_t fs_config) =
    	{
    		  .callback  = fs_evt_handler, // Function for event callbacks.
    			.num_pages = NUM_PAGES,      // Number of physical flash pages required.
    			.priority  = 0xFE,            // Priority for flash usage.
            .p_start_addr = (uint32_t*)0x57000,
            .p_end_addr = (uint32_t*)0x58000
    	};
    
  • Hello, the problem was from an other side, and it would be intersting for nordic to have a look at it.

    First of all , fs_init() should be call after softdevice initialization, otherwise that won't work, and the callback will never be serviced. I guess this is because of the queue managment, I don't have time to investigate deeper.

    Then, and the most important, I had to change the fstorage.c file. fs_erase function always returned FS_ERR_INVALID_ADDR, despite the address was valid.

    The test
    p_page_addr + (FS_PAGE_SIZE_WORDS * num_pages > p_config->p_end_addr
    was always true So I did add a temporary uint32_t variable and wrote the following code :

    tmp32 = FS_PAGE_SIZE_WORDS * num_pages + (uint32_t)p_page_addr;
        // Check that the operation doesn't go outside the client's memory boundaries.
        if ((p_page_addr < p_config->p_start_addr) ||
            ((tmp32) > (uint32_t)p_config->p_end_addr))
        {
            return FS_ERR_INVALID_ADDR;
        }
    

    The compiler is Keil µVision 5

Related