Hi
I am having a problem now(maybe a bug).I refer to nest_state.c and access.c build my user_flash.
But some time,when I reset device,write data to flah will be fail.
If repeatedly reset.when my load user data,will read some data from handle 0x220.But in fact I have not use this handle.
So,there are two problems:
1.When I calling function flash_manager_entry_alloc() AND flash_manager_entry_commit(), some time will be fail (In fact, it alternates, first reset will write success, the second reset wile write fail, the third reset will success).
2.if my write data success(handle value 0x0001), reset again and again, the function flash_manager_entries_read(), will callback the data from handle 0x220.
Attach my code of user_flash.c & user_flash.h
#include "user_flash.h" #include "log.h" #include "flash_manager.h" #include "nrf_mesh_assert.h" #include "nrf_mesh_events.h" #include "event.h" #include "access.h" #define USER_FLASH_PAGE_COUNT (1) #define FLASH_HANDLE_USER (0x0001) static flash_manager_t u_flash_manager; static user_flash_data_t m_user; static bool u_flash_not_ready = false; typedef void (*flash_op_func_t)(void); static void flash_mem_available(void * p_args) { NRF_MESH_ASSERT(p_args != NULL); flash_op_func_t func = (flash_op_func_t) p_args; /*lint !e611 Suspicious cast */ func(); } static void flash_write_complete(const flash_manager_t * p_manager, const fm_entry_t * p_entry, fm_result_t result) { __LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"write result:0x%X handle:0x%X\n",result,p_entry->header.handle); if (result == FM_RESULT_SUCCESS) { u_flash_not_ready = false; } else { NRF_MESH_ASSERT(result == FM_RESULT_ERROR_FLASH_MALFUNCTION); nrf_mesh_evt_t evt = { .type = NRF_MESH_EVT_FLASH_FAILED, .params.flash_failed.user = NRF_MESH_FLASH_USER_CORE, .params.flash_failed.p_flash_entry = p_entry, .params.flash_failed.p_flash_page = NULL, .params.flash_failed.p_area = u_flash_manager.config.p_area, .params.flash_failed.page_count = u_flash_manager.config.page_count, }; event_handle(&evt); } } const void * user_flash_area_get(void) { return (((const uint8_t *) access_flash_area_get()) - (USER_FLASH_PAGE_COUNT * PAGE_SIZE)); } static void flash_store_data(void) { fm_entry_t * p_new_entry = flash_manager_entry_alloc(&u_flash_manager, FLASH_HANDLE_USER, sizeof(user_flash_data_t)); if (p_new_entry == NULL) { /* try again later */ static fm_mem_listener_t mem_listener = {.callback = flash_mem_available, .p_args = flash_store_data}; flash_manager_mem_listener_register(&mem_listener); } else { user_flash_data_t * p_iv_index_data = (user_flash_data_t *) p_new_entry->data; p_iv_index_data->number = m_user.number; p_iv_index_data->setup = m_user.setup; flash_manager_entry_commit(p_new_entry); } } void user_flash_init(void) { __LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"user_flash_init\n"); flash_manager_config_t config; memset(&config, 0, sizeof(config)); config.min_available_space = 0; config.p_area = user_flash_area_get(); config.page_count = USER_FLASH_PAGE_COUNT; config.write_complete_cb = flash_write_complete; if (flash_manager_add(&u_flash_manager, &config) != NRF_SUCCESS) { static fm_mem_listener_t mem_listener = {.callback = flash_mem_available, .p_args = user_flash_init}; flash_manager_mem_listener_register(&mem_listener); }else { if (u_flash_manager.internal.state == FM_STATE_BUILDING) { m_user.number = 0; m_user.setup = 0; flash_store_data(); u_flash_not_ready = true; } } } static fm_iterate_action_t entry_recover_cb(const fm_entry_t * p_entry, void * p_args) { __LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"read handle:0x%X\n",p_entry->header.handle); user_entry_recover_context_t * p_context = p_args; switch (p_entry->header.handle) { case FLASH_HANDLE_USER: p_context->user = (const user_flash_data_t *) p_entry->data; break; default: break; } return FM_ITERATE_ACTION_CONTINUE; } void user_state_recover_from_flash(void) { bearer_event_critical_section_begin(); if(u_flash_not_ready) { } else { user_entry_recover_context_t context = {NULL}; uint32_t status = flash_manager_entries_read(&u_flash_manager, NULL, entry_recover_cb, &context); if (context.user == NULL ) { m_user.number = 0; m_user.setup = 0; flash_store_data(); } else { m_user.number = context.user->number; m_user.setup = context.user->setup; } } bearer_event_critical_section_end(); } void user_state_storad_flash(uint16_t num,uint16_t stp) { m_user.number = num; m_user.setup = stp; flash_store_data(); }