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

[MESH SDK] Call dsm from main loop cause Assertion error

Hi,

Actually in my program I have a serial uart interface that cause an interrupt when a message is receive. During the interrupt, I send a mesh model command and its works.

But if I put my serial messages in a queue and then I dequeue them in the main loop, I got an "Assertion Failed Error at: 0" when I try to send a mesh model command, especially if I need to change the publish address of the model before sending the command. But even if I just send the command without using the dsm function to change the publish address, I got the same error.

So how can I send a mesh model message (using the dsm to change the publish address of a model before sending) from the main loop ?

Regards

The command sending code that works when its called from uart interrupt and not from main loop.

The assertions are raised by "dsm_address_publish_add" and "access_model_publish_address_set"

uint8_t send_hx_cmd(uint16_t dest, uint8_t* cmd)
{
  dsm_handle_t hdl;
  uint32_t res = dsm_address_publish_add(dest, &hdl);
  if (res != NRF_SUCCESS)
  {
    return SERIAL_ERROR;
  }

  res = access_model_publish_address_set(m_hx_model_control.model_handle, hdl);
  if (res != NRF_SUCCESS)
  {
    return SERIAL_ERROR;
  }

  static uint8_t cmd_data[SERIAL_COMMAND_SIZE];
  cmd_data[0] = 0x00;

  memcpy( &cmd_data[1], &cmd[0], 29 );

  res = hx_model_client_opcode_tx(&m_hx_model_control.client_model, cmd_data, SERIAL_COMMAND_SIZE);
  if (res != NRF_SUCCESS)
  {
    return SERIAL_ERROR;
  }

  return SERIAL_CMD_SUCCESS;
}

The function that cause the assertion error (in mesh_config.c) .

The assertion is raised by   "dirty_entries_process();"

static uint32_t entry_store(const mesh_config_entry_params_t * p_params, mesh_config_entry_id_t id, const void * p_entry)
{
    uint32_t status = p_params->callbacks.setter(id, p_entry);
    if (status == NRF_SUCCESS)
    {
        mesh_config_entry_flags_t * p_flags = entry_flags_get(p_params, id);
        *p_flags |= (mesh_config_entry_flags_t)(MESH_CONFIG_ENTRY_FLAG_DIRTY | MESH_CONFIG_ENTRY_FLAG_ACTIVE);
        const mesh_config_file_params_t * p_file = file_params_find(p_params->p_id->file);
        NRF_MESH_ASSERT(p_file != NULL);
        dirty_entries_process();
        listeners_notify(p_params, MESH_CONFIG_CHANGE_REASON_SET, id, p_entry);
    }

    return status;
}

Used sdk :

- nRF5_SDK_16.0.0_98a08e2

- nrf5_SDK_for_Mesh_v4.2.0_src

Board used :

- nrf52840 evaluation board v2.0.1

  • Hi Neicureuil, 

    If you have a look here, you can find that if you call mesh_init() with NRF_MESH_IRQ_PRIORITY_LOWEST , then you would need to call mesh APIs from the interrupt handler at NRF_MESH_IRQ_PRIORITY_LOWEST level. You can't call Mesh API in the main loop. 
    Otherwise you need to initialize mesh with NRF_MESH_IRQ_PRIORITY_THREAD then you should not call Mesh APIs in an interrupt handler. 

    If you want to call mesh API in both contexts, you would need to either use a software interrupt and call the interrupt from the main loop when you use NRF_MESH_IRQ_PRIORITY_LOWEST  , or the opposite, use app_scheduler if you use NRF_MESH_IRQ_PRIORITY_THREAD .

Related