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

Writing Data to flash with fstorage libraray using SDK13.1

Hi,

I want to write data to the Flash memory of my Nordic thingy 52 board.

When I erase flash using API ret = fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL);  return code is zero.

After erasing the flash when I read the content of the flash it must be 0xFFFFFFFF but in my case it is some random value.

After eraing flash i write data = 0xAAAAAAAA to the start address of the page I erase using API given below,

ret = fs_store(&fs_config, (fs_config.p_start_addr), &data, 1, NULL);

where data is 0xAAAAAAAA

Return code of the the API is 0(NRF_SUCCESS).

After writing the data when I read from the particular address i got some random data 0x60000000.

For reference | attached a log below,

Erasing a flash page at address 0x70000
return code erase = 0x0
Data read from flash address 0x70000: 60000000
Data read from flash address 0x70004: 60000000
Data read from flash address 0x70008: ffffffff
Data read from flash address 0x7000C: ffffffff
Writing data 0xAAAAAAAA to address 0x70000
return code fs_store AAAAAAAA = 0x0

For reference attaching the code below.

volatile uint32_t data;
uint32_t flash_data[4];
FS_REGISTER_CFG(fs_config_t fs_config) =
{
.callback = fs_event_handler1, // Function for event callbacks.
// .num_pages = NUM_PAGES, // Number of physical flash pages required.
// .priority = 0xFF // Priority for flash usage.
.num_pages = 1,
.p_start_addr = 0x00070000, // Start Address of Reserved Free Space
.p_end_addr = 0x00071000,
.priority = 0xFE
//priority = 0x01
};

fs_ret_t ret = fs_init(); //initializing flash storage
NRF_LOG_RAW_INFO("return code of fs_init() = 0x%d\r\n", ret); //printing return code for fs_init() function
NRF_LOG_RAW_INFO("Erasing a flash page at address 0x%X\r\n", fs_config.p_start_addr);
ret = fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL); //Erasing a single page from start address
NRF_LOG_RAW_INFO("return code erase = 0x%d\r\n", ret); //printing return code for fs_erase


//Read the first 4 words of the page
for (int i = 0; i < 4; i++) {
NRF_LOG_RAW_INFO("Data read from flash address 0x%X: ", fs_config.p_start_addr + i);
flash_data[i] = *(fs_config.p_start_addr + i);
NRF_LOG_RAW_INFO("%x ", flash_data[i]);
NRF_LOG_RAW_INFO("\r\n");
}

data = 0xBBBBBBBB;
NRF_LOG_RAW_INFO("Writing data 0x%X to address 0x%X\r\n", data, fs_config.p_start_addr);
fs_callback_flag = 1;
ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1, NULL);
NRF_LOG_RAW_INFO("return code fs_store BBBBBBBB= 0x%d\r\n", ret); //printing return code for fs_erase

data = 0xAAAAAAAA;
NRF_LOG_RAW_INFO("Writing data 0x%X to address 0x%X\r\n", data, fs_config.p_start_addr + 1);
fs_callback_flag = 1;
ret = fs_store(&fs_config, (fs_config.p_start_addr + 1), &data, 1, NULL);
NRF_LOG_RAW_INFO("return code fs_store AAAAAAAA = 0x%d\r\n", ret); //printing return code for fs_erase

flash_data[0] = *(fs_config.p_start_addr);
flash_data[1] = *(fs_config.p_start_addr + 1);
NRF_LOG_RAW_INFO("read data at flash_data[0] = %x\r\n", flash_data[0]); //printing data at fs_config.p_start_addr
NRF_LOG_RAW_INFO("read data at flash_data[1] = %x\r\n", flash_data[1]); //printing data at fs_config.p_start_addr + 1
}

Output of the program is given below,

Erasing a flash page at address 0x70000

return code erase = 0x0
Data read from flash address 0x70000: 60000000
Data read from flash address 0x70004: 60000000
Data read from flash address 0x70008: ffffffff
Data read from flash address 0x7000C: ffffffff
Writing data 0xBBBBBBBB to address 0x70000
return code fs_store BBBBBBBB= 0x0
Writing data 0xAAAAAAAA to address 0x70004
return code fs_store AAAAAAAA = 0x0
read data at flash_data[0] = 60000000
read data at flash_data[1] = 60000000

Thanks,
Raj

Parents
  • Hi,

    Erasing and writing flash are time consuming operations, and they are not performed immediately. Instead they are put in a queue. You get an event when the operation has finished (either succeeded or failed), which is handled by the callback handler that you registered with FS_REGISTER_CFG.

    It looks from the code like you want to use fs_callback_flag for signalling that an operation has started, then set that flag back to 0 in the callback handler when the operation is finished, and wait in main for the flag to have been set back to 0 before you go on to the next operation. But you do not have code in place for the last step of waiting for the flag to be reset to 0.

    For more information on how to handle flash and the fstorage library, you can have a look at the Flash Storage library documentation and the fstorage API documentation. While the names of the API calls may have changed for later SDK versions, in nRF5 SDK v14.1.0 and later there is a Flash Storage Example that shows one way to handle the waiting until the event before moving on to the next flash operation.

    Regards,
    Terje

  • Hi Tesc,

     Yes , you are right I am using fs_callback_flag for signalling that an operation has started, then set that flag back to 0 in the callback handler when the operation is finished, and wait in main for the flag to have been set back to 0 before go on to the next operation,  But the problem is when I used the approach as you suggested my code get stucks in while(fs_callback_flag) and callback never hits.

    For your reference I attached the code with the implementation as you suggested below,

    volatile uint32_t data;
    uint32_t flash_data;
    volatile uint8_t fs_callback_flag;
    
    /****************************************************************************/
    
    /***************************************************************************/
    
    static void fs_event_handler1(fs_evt_t const * const evt, fs_ret_t result)
    {
        if (result != FS_SUCCESS)
        {
            bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
        }
    		else
    		{
    		                         fs_callback_flag = 0;
                                     NRF_LOG_RAW_INFO("callback hit.....\r\n");
    				
    		}
    }
    
    
    FS_REGISTER_CFG(fs_config_t fs_config) =
    {
    .callback = fs_event_handler1, // Function for event callbacks.
    // .num_pages = NUM_PAGES, // Number of physical flash pages required.
    // .priority = 0xFF // Priority for flash usage.
    .num_pages = 1,
    .p_start_addr = 0x00070000, // Start Address of Reserved Free Space
    .p_end_addr = 0x00071000,
    .priority = 0xFE
    //priority = 0x01
    };
    
    fs_ret_t ret = fs_init(); //initializing flash storage
    NRF_LOG_RAW_INFO("return code of fs_init() = 0x%d\r\n", ret); //printing return code for fs_init() function
    NRF_LOG_RAW_INFO("Erasing a flash page at address 0x%X\r\n", fs_config.p_start_addr);
    ret = fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL); //Erasing a single page from start address
    NRF_LOG_RAW_INFO("return code erase = 0x%d\r\n", ret); //printing return code for fs_erase
    fs_callback_flag = 1;
    while(fs_callback_flag);//......................my code stucks here..........................
    
    //Read the first 4 words of the page
    for (int i = 0; i < 4; i++) {
    NRF_LOG_RAW_INFO("Data read from flash address 0x%X: ", fs_config.p_start_addr + i);
    flash_data[i] = *(fs_config.p_start_addr + i);
    NRF_LOG_RAW_INFO("%x ", flash_data[i]);
    NRF_LOG_RAW_INFO("\r\n");
    }
    
    data = 0xBBBBBBBB;
    NRF_LOG_RAW_INFO("Writing data 0x%X to address 0x%X\r\n", data, fs_config.p_start_addr);
    ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1, NULL);
    fs_callback_flag = 1;
    while(fs_callback_flag);
    NRF_LOG_RAW_INFO("return code fs_store BBBBBBBB= 0x%d\r\n", ret); //printing return code for fs_erase
    
    data = 0xAAAAAAAA;
    NRF_LOG_RAW_INFO("Writing data 0x%X to address 0x%X\r\n", data, fs_config.p_start_addr + 1);
    ret = fs_store(&fs_config, (fs_config.p_start_addr + 1), &data, 1, NULL);
    fs_callback_flag = 1;
    while(fs_callback_flag);
    NRF_LOG_RAW_INFO("return code fs_store AAAAAAAA = 0x%d\r\n", ret); //printing return code for fs_erase
    
    flash_data[0] = *(fs_config.p_start_addr);
    flash_data[1] = *(fs_config.p_start_addr + 1);
    NRF_LOG_RAW_INFO("read data at flash_data[0] = %x\r\n", flash_data[0]); //printing data at fs_config.p_start_addr
    NRF_LOG_RAW_INFO("read data at flash_data[1] = %x\r\n", flash_data[1]); //printing data at fs_config.p_start_addr + 1
    }

    And the link you provide  Flash Storage Example is applicable for SDK14.1 but i am using SDK13.1 as nordic thingy 52 board is based on SDK13.1

    Thanks,

    Raj 

     

    Thanks,

    Raj

  • Hi,

    When using that code, do you get the log output of "callback hit....."? Can you add similar debug print to the other branch of the if as well, to confirm that you get one or the other?

    Regards,
    Terje

  • Hi,

    While using the code I didn't get the log output of    "callback hit....."  & code stucks in the first while(fs_callback_flag); after fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL);

    For your reference attaching the logs of the code  and code below 

    static void fs_event_handler1(fs_evt_t const * const evt, fs_ret_t result)
    {
        if (result != FS_SUCCESS)
        {
           // bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
           NRF_LOG_RAW_INFO("callback hit unsucess.....\r\n");
    
        }
    		else
    		{                fs_callback_flag = 0;
                                     NRF_LOG_RAW_INFO("callback hit success.....\r\n");
    				//printf("    fstorage command successfully completed   \n\r");
    				
    		}
    }
    

    Logs

    main :INFO:[1;32m===== Thingy started! =====
    return code of fs_init() = 0x0
    Erasing a flash page at address 0x70000
    return code erase = 0x0

    Thanks,

    Raj

  • Hi,

    Right, so you do not get into fs_event_handler1 at all?

    If this is a modification of the Thingy firmware then it is using Peer Manager, which uses Flash Data Storage (FDS), which again uses flash storage (fstorage). Depending on FDS configuration, the flash page at 0x70000 may or may not be part of what is used by FDS. How many pages are reserved for FDS in your project, is there some overlap there?

    Also, please check that you only initialize fstorage once in the project, and that it happens after all the configurations are registered with FS_REGISTER_CFG. If using Peer Manager / FDS, I suspect that fstorage has already been initialised by FDS when you run the line fs_ret_t ret = fs_init();. What value does fs_init() return, I see that you print it but you have not shared the log output.

    Regards,
    Terje

Reply
  • Hi,

    Right, so you do not get into fs_event_handler1 at all?

    If this is a modification of the Thingy firmware then it is using Peer Manager, which uses Flash Data Storage (FDS), which again uses flash storage (fstorage). Depending on FDS configuration, the flash page at 0x70000 may or may not be part of what is used by FDS. How many pages are reserved for FDS in your project, is there some overlap there?

    Also, please check that you only initialize fstorage once in the project, and that it happens after all the configurations are registered with FS_REGISTER_CFG. If using Peer Manager / FDS, I suspect that fstorage has already been initialised by FDS when you run the line fs_ret_t ret = fs_init();. What value does fs_init() return, I see that you print it but you have not shared the log output.

    Regards,
    Terje

Children
No Data
Related