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

Mesh Flash Manager

On SDK16.0.0 + Mesh SDK 4.1.0

I am trying to store some user data using the Flash Manager. I am modifying the light switch server mesh example.

There are a lot of posts about this, but none of them have a final answer how to get it done.

Here is what I have so far:

#define FLASH_CUSTOM_DATA_GROUP_ELEMENT 0x4748
#define CUSTOM_DATA_FLASH_PAGE_COUNT 1

typedef struct {
    uint8_t data[256];
} custom_data_format_t;

static flash_manager_t m_custom_data_flash_manager;

Then in main(), just before the forever for loop (after everything has been initialized:

uint32_t ret_code;
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;

//custom_data_manager_config.p_area = (const flash_manager_page_t *)(((const uint8_t *)flash_manager_recovery_page_get()) - (ACCESS_FLASH_PAGE_COUNT * PAGE_SIZE) - (NET_FLASH_PAGE_COUNT * PAGE_SIZE));
custom_data_manager_config.p_area = (const flash_manager_page_t *)(((const uint8_t *)flash_manager_recovery_page_get()) - (10 * PAGE_SIZE));

__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "user area: 0x%08x \n", custom_data_manager_config.p_area);
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: %u\n", ret_code);
}
else {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "flash_manager_add() successful\n");
}

// Write to 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;
    
    // Generate test data
    for(uint8_t i=0; i<256; i++) {
        p_custom_data->data[i] = i;
    }
    
    // Write
    flash_manager_entry_commit(p_entry);
}

// Wait for flash manager to finish.
flash_manager_wait();

// Read back test data
const fm_entry_t * p_read_raw1 = 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_raw1->data;
for(uint8_t i=0; i<256; i++) {
   __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "p_read_data[%u]: %u\n", i, p_read_data[i]);
}

This keeps on asserting somewhere after the flash_manager_add().

I am not sure how to calculate the custom_data_manager_config.p_area correctly. All the examples referred to ACCESS_FLASH_PAGE_COUNT and NET_FLASH_PAGE_COUNT, which is not used anymore. I tried not offsetting by anything and I tried to offset it by 10 pages.

Thanks.

Parents
  • Hi Ferdi, 

    It's not recommended to use the flash_manager directly. 
    Instead we suggest to use the mesh config module to store your own data instead. 
    You can find the documentation with example code here.
    You can also have a look at our Enocean_switch example to see how it's implemented. In the example we store the state of the light switch to flash when we receive a packet. 

  • Oh, I've never even heard about the mesh config module.

    - Is there some more information about how to use default values?

    - If mesh_config_entry_set() returns NRF_SUCCESS, can one assume that the values have been successfully stored? The documentation mentions waiting for NRF_MESH_EVT_CONFIG_STABLE event or checking via mesh_config_is_busy(), but the enocean example doesn't do this.

    - Since the backend is based on Flash Manager, I assume that defragmentation, power failure protection, etc is all taken care of?

    Thanks.

Reply
  • Oh, I've never even heard about the mesh config module.

    - Is there some more information about how to use default values?

    - If mesh_config_entry_set() returns NRF_SUCCESS, can one assume that the values have been successfully stored? The documentation mentions waiting for NRF_MESH_EVT_CONFIG_STABLE event or checking via mesh_config_is_busy(), but the enocean example doesn't do this.

    - Since the backend is based on Flash Manager, I assume that defragmentation, power failure protection, etc is all taken care of?

    Thanks.

Children
  • - Yes defragmentation and power failure protection is taken care of in flash manger which mesh config running on top. 
    - The documentation is what we have, we don't have other guides for this module. I would suggest to read about them in the code. 

    In the Enocean we don't check if the storage is successful or not as we don't have other task need to wait for that to finish. But you can have a look at the restored_result_apply() function  in netstate.c. persist_completed_notify() event handler is added when we do seqnum_block_allocate().

Related