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

Mesh SDK Flash Manager

Hi,

I'm testing the below example code, found on devzone, on mesh sdk 2.2.0.

int main(void)
{
    uint32_t ret_code;

    __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Light Switch Client Demo -----\n");

    hal_leds_init();
    ERROR_CHECK(hal_buttons_init(button_event_handler));

    /* Set the first LED */
    hal_led_pin_set(BSP_LED_0, true);
    mesh_core_setup();
    access_setup();
    rtt_input_enable(rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);

    /* Adding custom data to flash for persistent storage */

    // 1) Flash manager is already initialized

    // 2) Add a new flash manager instance. NB: should not overlap (in region) the instance used by mesh.  

    flash_manager_config_t custom_data_manager_config;
    custom_data_manager_config.write_complete_cb = NULL; 
    custom_data_manager_config.invalidate_complete_cb = NULL; 
    custom_data_manager_config.remove_complete_cb = NULL; 
    custom_data_manager_config.min_available_space = WORD_SIZE;

    // The new instance of flash manager should use an unused region of flash:
    custom_data_manager_config.p_area = (const flash_manager_page_t *) (((const uint8_t *) dsm_flash_area_get()) - (ACCESS_FLASH_PAGE_COUNT * PAGE_SIZE) - (NET_FLASH_PAGE_COUNT * PAGE_SIZE) );
    
    custom_data_manager_config.page_count = CUSTOM_DATA_FLASH_PAGE_COUNT;
   
    ret_code = flash_manager_add(&m_custom_data_flash_manager, &custom_data_manager_config);
   
    if (NRF_SUCCESS != ret_code) {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Flash error: no memory\n",ret_code);
    
    }
   
    
    // 3) Write to Flash

    // a) allocate flash 
    fm_entry_t * p_entry = flash_manager_entry_alloc(&m_custom_data_flash_manager, FLASH_CUSTOM_DATA_GROUP_ELEMENT, sizeof(custom_data_format_t));
    if (p_entry == NULL)
    {
      return NRF_ERROR_BUSY;
    }
      else
    {
       
      custom_data_format_t * p_custom_data = (custom_data_format_t *) p_entry->data;
      p_custom_data->data[0] = 5;
      p_custom_data->data[1] = 9;
   
      // b) write to flash
      flash_manager_entry_commit(p_entry);
      __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "write:%x, %x\n",p_entry->data[0], p_entry->data[1]);
      
    }
    
    
    // 4) Wait for flash manager to finish.
    flash_manager_wait();
   
   
    
    // 5) Read from Flash
    const fm_entry_t * p_read_raw = flash_manager_entry_get(&m_custom_data_flash_manager, FLASH_CUSTOM_DATA_GROUP_ELEMENT);
    
    const custom_data_format_t * p_read_data = (const custom_data_format_t *) p_read_raw->data;
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "read:%x, %x\n",p_read_data->data[0], p_read_data->data[1]);
    



    while (true)
    {
        (void)sd_app_evt_wait();
    }
}

I'm experiencing a strange issue on the read side.
On the first read after the write I always read the old value, not the just written data.
Then on the first execution of the above code, it writes 0x5, 0x09 and it reads some garbage because the flash was never written before.
On the second execution I write and read the same.
If I change the written data, on the first read I continue reading 0x05, 0x09 and from the second read on I read the new data.

It seams that flash_manager_wait() is not working properly.
Have you an idea of the reason of this behavior?


Thank you
Lucio

Parents Reply
  • Hi Bjørn,

    why you do not recommend the above code?

    It uses exacly the APIs listed in the 2.2.0 flash manager API documentation you mentioned.

    Do you have any example code?

    The issue I submitted in this ticket is related to the flash_manager_wait() API which is listed in the API documentation you mentioned, but to me, it seems that it does not wait the previous write to terminate and be ready to read it back again.

    Maybe I'm missing something?

    Lucio

Children
  • Hi Lucio,

    Sorry about that. You are correct that the API is the same. For your usecase, it does not matter that the flash manager code has been updated significantly under the hood.

    Regarding example code, I would just take a look at one of the mesh sdk examples (light switch) & seeing how the flash manager code is used there (e.g. see the load_app_data() in main.c of the provisioner example).

    However, there have been issues with the flash_manager_wait() function. Which IRQ priority are you running the mesh in (see doc for more info)? It may be that this issue arises do to the wrong IRQ priority.

    It may be a better idea to use asynchronous events instead of the flash_manager_wait() function to wait. See the light switch provisioning doc & provisioning example for an example of this in action.

    Kind Regards,

    Bjørn

Related