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

NRF_MESH_ERROR_CHECK(sd_radio_session_open()) fails in timeslot_start() due to ISR recursion

Nodrdic stack asserts in timeslot_start() call, when calling sd_radio_session_open().

uint32_t timeslot_start(void)
{
switch (m_current_timeslot.session_state)
{
case TS_SESSION_STATE_CLOSED:
NRF_MESH_ERROR_CHECK(sd_radio_session_open(radio_signal_callback));
/* fallthrough */
case TS_SESSION_STATE_OPEN:
NRF_MESH_ERROR_CHECK(sd_radio_request(&m_radio_request_earliest));
m_current_timeslot.session_state = TS_SESSION_STATE_RUNNING;
break;

case TS_SESSION_STATE_RUNNING:
/* already started */
return NRF_ERROR_BUSY;
}
return NRF_SUCCESS;
}

When we set a breakpoint on this failure in Segger Embedded Studio, it appears timeslot_start() is being interrupted and then the ISR calls this function again, causing the assert.

  • Possible fix:


    uint32_t timeslot_start(void)
    {
    switch (m_current_timeslot.session_state)
    {
    case TS_SESSION_STATE_CLOSED:
    m_current_timeslot.session_state = TS_SESSION_STATE_STARTING;
    NRF_MESH_ERROR_CHECK(sd_radio_session_open(radio_signal_callback));
    /* fallthrough */
    case TS_SESSION_STATE_OPEN:
    NRF_MESH_ERROR_CHECK(sd_radio_request(&m_radio_request_earliest));
    m_current_timeslot.session_state = TS_SESSION_STATE_RUNNING;
    break;

    case TS_SESSION_STATE_RUNNING:
    case TS_SESSION_STATE_STARTING:
    /* already started */
    /* or this call was interrupted and the ISR calls it again */
    return NRF_ERROR_BUSY;
    }
    return NRF_SUCCESS;
    }

Related