I am encountering an issue with PERSISTENT_STORAGE enabled. Currently I have a device set up to rapidly send out messages to test the sequence number updating and block allocation procedure. I notice that when the sequence number approaches the next block by (NETWORK_SEQNUM_FLASH_BLOCK_THRESHOLD) amount and triggers the seqnum_block_allocate() (see the code snippet below) I get a mesh assertion error.
uint32_t net_state_seqnum_alloc(uint32_t * p_seqnum) { // Attempt to allocate the sequence number before it is fully restored from persistent storage. if (!m_status.is_synchronized) { return NRF_ERROR_FORBIDDEN; } if (m_net_state.seqnum < m_net_state.seqnum_max_available) { /* Check if we've reached the seqnum threshold for a state transition. */ uint32_t threshold = NETWORK_SEQNUM_IV_UPDATE_START_THRESHOLD; if (m_net_state.iv_update.state == NET_STATE_IV_UPDATE_IN_PROGRESS) { threshold = NETWORK_SEQNUM_IV_UPDATE_END_THRESHOLD; } bool ivu_triggered = false; if (m_net_state.seqnum >= threshold) { m_net_state.iv_update.pending = true; ivu_triggered = iv_update_trigger_if_pending(); } if (!ivu_triggered && m_net_state.seqnum >= m_net_state.seqnum_max_available - NETWORK_SEQNUM_FLASH_BLOCK_THRESHOLD) { seqnum_block_allocate(); } /* Get the sequence number after doing the state updates, as they might * trigger changes to it. */ uint32_t was_masked; _DISABLE_IRQS(was_masked); *p_seqnum = m_net_state.seqnum++; _ENABLE_IRQS(was_masked); return NRF_SUCCESS; } else { seqnum_block_allocate(); return NRF_ERROR_FORBIDDEN; } }
Mesh assertion error at line NRF_MESH_ASSERT_DEBUG(*p_flags & MESH_CONFIG_ENTRY_FLAG_BUSY); in the code:
static void backend_evt_handler(const mesh_config_backend_evt_t * p_evt) { const mesh_config_entry_params_t * p_params = entry_params_find(p_evt->id); if (p_params == NULL && MESH_CONFIG_BACKEND_EVT_TYPE_ERASE_COMPLETE == p_evt->type) { /* Check whether entry with known file id was deleted. */ const mesh_config_file_params_t * p_file = file_params_find(p_evt->id.file); NRF_MESH_ASSERT(p_file); return; } NRF_MESH_ASSERT(p_params); mesh_config_entry_flags_t * p_flags = entry_flags_get(p_params, p_evt->id); NRF_MESH_ASSERT_DEBUG(*p_flags & MESH_CONFIG_ENTRY_FLAG_BUSY); *p_flags &= (mesh_config_entry_flags_t)~MESH_CONFIG_ENTRY_FLAG_BUSY; if (p_evt->type == MESH_CONFIG_BACKEND_EVT_TYPE_STORAGE_MEDIUM_FAILURE) { const nrf_mesh_evt_t evt = { .type = NRF_MESH_EVT_CONFIG_STORAGE_FAILURE, .params.config_storage_failure = { .id = p_evt->id, /*lint !e64 Type mismatch */ } }; event_handle(&evt); } if (mesh_config_is_busy()) { dirty_entries_process(); } else { m_emergency_action = false; nrf_mesh_evt_t evt = {.type = NRF_MESH_EVT_CONFIG_STABLE}; event_handle(&evt); } }
Callstack:
What is this assertion trying to achieve and any ideas why its being triggered?
If I continue to let the application run, the next time it attempts to allocate a sequence block it fails repeatedly until the "if (m_net_state.seqnum < m_net_state.seqnum_max_available)" check fails and starts returning NRF_ERROR_FORBIDDEN.
Using mesh v4.1