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.

Parents
  • 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

Reply
  • 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

Children
No Data
Related