Guys,
In a Mesh project, when setting up flash manager:
- How do you get the right value of flash_manager_config_t.p_area?
- And where and how is it configured?
Thanks...
Guys,
In a Mesh project, when setting up flash manager:
Thanks...
Hello,
Is there a particular reason why you need to change this? Did you encounter any issues?
The p_area is the address to the start address that should be used by the flash manager. If you look at any of the examples in the Mesh SDK, you can see that in mesh_config_flashman_glue.c -> mesh_config_backend_file_create(), p_area is set to:
p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE));
The function flash_area_end_get() (via a lot of functions) points to mp_recovery area, which again is set based on whether or not you have a bootloader programmed, via the BOOTLOADERADDR(), which is a macro that checks the chip's bootloader address register.
I guess that answers both 1. and 2. Check out mesh_config_backend_file_create(), and the function flash_manager_defrag_init() in flash_manager_defrag.c.
Best regards,
Edvin
Edvin,
If somehow possible please provide a demo and a few lines of explanation that clarify how to set up flash manager in an application. TBH, flashmanager's documentation is total cr@p not helpful (api docs are a little better, but still insufficient). And looking at any of the examples in the Mesh SDK doesn't explain much neither. See, I'm really not in the mood of copy&pasting some code I don't understand...
So a little example would help a lot!
Thanks for your help,
Michael.
An example that uses the flash manager would be e.g. the Mesh_SDK_5.0.0\examples\light_switch\server
But I guess you already knew that, and that this is not what you are looking for.
Perhaps you can tell me what you intend to do. Do you intend to store some custom data, and hence you want an own instance of the flash manager? Or do you encounter some issues with the flash manager being used to store the Mesh network data?
BlueMike said:The demo code from one of the posts here on devzone looks like as if p_area is an input parameter (and hence needs to be provided).
Well, it is both.
Every instance of the flash manager is set up from a start address (p_area) and a size page_count.
The function mesh_config_backend_file_create() in mesh_config_flashman_glue.c is a good example on how to set this up:
uint32_t mesh_config_backend_file_create(mesh_config_backend_file_t * p_file)
{
uint8_t page_count;
flash_manager_page_t * p_area;
#if !(BACKWARD_COMPATIBLE_PERSISTENCE)
page_count = CEIL_DIV(p_file->size, FLASH_MANAGER_DATA_PER_PAGE);
#else
legacy_flash_config_get(p_file, &page_count, &p_area);
if (p_area == NULL)
#endif
{
m_allocated_page_count += page_count;
p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE));
}
flash_manager_t * p_manager = &p_file->glue_data.flash_manager;
const flash_manager_config_t config =
{
.write_complete_cb = write_complete_cb,
.invalidate_complete_cb = invalidate_complete_cb,
.remove_complete_cb = remove_complete_cb,
.min_available_space = p_file->size,
.p_area = p_area,
.page_count = page_count
};
__LOG(LOG_SRC_FM, LOG_LEVEL_DBG3, "Mesh config area: 0x%08x file_id: 0x%04x\n",
config.p_area, p_file->file_id);
return flash_manager_add(p_manager, &config);
}
BlueMike said:If yes: Is it safe to use the same value that other instances use? I.e. just copy the line:
p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE));
Yes. If you intend to use the same flash manager instance (you can do that). If you want to use a separate instance with it's own area, you need to customise this a bit. As you may notice, the area used for the flash manager is the end of the flash. If a bootloader is used, then the flash manager is placed right before the bootloader.
Let's assume you want to create your own instance with it's own flash area, then the flash manager instance that is used for the network area is already considering whether a bootloader is present or not. You can either use the p_area and adjust it, or the implementation that it uses.
p_custom_area = p_area - CUSTOM_FLASH_MANAGER_PAGE_COUNT; or: p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE)) - CUSTOM_FLASH_MANAGER_PAGE_COUNT; ... .p_area = p_custom_area, .page_count = CUSTOM_FLASH_MANAGER_PAGE_COUNT,
And CUSTOM_FLASH_MANAGER_PAGE_COUNT is the amount of flash pages you want to set aside for your custom flash manager instance.
Best regards,
Edvin
An example that uses the flash manager would be e.g. the Mesh_SDK_5.0.0\examples\light_switch\server
But I guess you already knew that, and that this is not what you are looking for.
Perhaps you can tell me what you intend to do. Do you intend to store some custom data, and hence you want an own instance of the flash manager? Or do you encounter some issues with the flash manager being used to store the Mesh network data?
BlueMike said:The demo code from one of the posts here on devzone looks like as if p_area is an input parameter (and hence needs to be provided).
Well, it is both.
Every instance of the flash manager is set up from a start address (p_area) and a size page_count.
The function mesh_config_backend_file_create() in mesh_config_flashman_glue.c is a good example on how to set this up:
uint32_t mesh_config_backend_file_create(mesh_config_backend_file_t * p_file)
{
uint8_t page_count;
flash_manager_page_t * p_area;
#if !(BACKWARD_COMPATIBLE_PERSISTENCE)
page_count = CEIL_DIV(p_file->size, FLASH_MANAGER_DATA_PER_PAGE);
#else
legacy_flash_config_get(p_file, &page_count, &p_area);
if (p_area == NULL)
#endif
{
m_allocated_page_count += page_count;
p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE));
}
flash_manager_t * p_manager = &p_file->glue_data.flash_manager;
const flash_manager_config_t config =
{
.write_complete_cb = write_complete_cb,
.invalidate_complete_cb = invalidate_complete_cb,
.remove_complete_cb = remove_complete_cb,
.min_available_space = p_file->size,
.p_area = p_area,
.page_count = page_count
};
__LOG(LOG_SRC_FM, LOG_LEVEL_DBG3, "Mesh config area: 0x%08x file_id: 0x%04x\n",
config.p_area, p_file->file_id);
return flash_manager_add(p_manager, &config);
}
BlueMike said:If yes: Is it safe to use the same value that other instances use? I.e. just copy the line:
p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE));
Yes. If you intend to use the same flash manager instance (you can do that). If you want to use a separate instance with it's own area, you need to customise this a bit. As you may notice, the area used for the flash manager is the end of the flash. If a bootloader is used, then the flash manager is placed right before the bootloader.
Let's assume you want to create your own instance with it's own flash area, then the flash manager instance that is used for the network area is already considering whether a bootloader is present or not. You can either use the p_area and adjust it, or the implementation that it uses.
p_custom_area = p_area - CUSTOM_FLASH_MANAGER_PAGE_COUNT; or: p_area = (flash_manager_page_t *)(flash_area_end_get() - (m_allocated_page_count * PAGE_SIZE)) - CUSTOM_FLASH_MANAGER_PAGE_COUNT; ... .p_area = p_custom_area, .page_count = CUSTOM_FLASH_MANAGER_PAGE_COUNT,
And CUSTOM_FLASH_MANAGER_PAGE_COUNT is the amount of flash pages you want to set aside for your custom flash manager instance.
Best regards,
Edvin