Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Softdevice assert (id:0x1 pc:1089e info:0x0)

Our product uses non-connectable/undirected advertising, where advertisement packets are sent every 1 minute for 500ms time. For that we are using FreeRTOS timers to start/stop advertisement.The problem is that randomly either right after the advertisement is started or during the advertisement, app_erro_fault_handler() gets called leading to the system reset (id: 0x1 pc: 0x1089e info: 0x0). What might be the cause based on the given program counter or where would be the best place to start looking for the possible cause for the assert? I cannot disclose  all the specifics about the product sw/hw due NDA but basically we are using nRF52SDKI v12.10 with S132 v3.0.0. Ble control code is modified by removing all the heart sensor etc. related code and just sending specific advertisement packets.

  • Hi,

    Sami-Pekka Mähönen said:
    I had my device on testing overnight and there were lots of resets still.

    Are you still getting the assert with pc: 0x1089e ? or is this a new issue? Generally, a reset indicates that you are running into the error handler (APP_ERROR_CHECK), where the default behavior is to do a reset. You should then debug in order to find the reason for the reset, and you should have the preprocessor symbol DEBUG defined when debugging. See e.g. this post about debugging.

    You should be able to change the manufacturing data like you are doing without stopping the advertising. The SD will not get flooded. But, you could of course try to stop the advertising before you change it, and see if it makes any difference.

  • Hey,

    Ok, I just wanted to be sure that I'm not doing something wrong by changing advertising data without stopping advertisement first. 

    I enabled logs and seems that the program counter that I'm seeing now has changed to 0x1117C.Further debugging is not an option as we build our project with Eclipse and not with Keil.

    id: 0x1 pc: 0x1117C info: 0

    To be noted that assert is no longer as easy to reproduce as originally. 

  • Update: I have done some changes to our implementation regarding timers etc. Assert is still happening but with different program counter. Since the original pc has changed and to keep this thread minimal I will create another ticket with updated info and verify the suggestion to update SD from 3.0.0 to 4.0.5 as answer to original problem.

  • Are you still getting assert with pc: 0x1117C on 4.0.5 ?

  • Hey,

    Yes, I made changes so that instead of starting and stopping with FreeRTOS timers, I have set advertising timeout to 1 second. When on_adv_evt(BLE_ADV_EVT_IDLE) gets called after timeout, timer using nrf_drv_timer_*() is started. Once that timer timeouts, advertising is started again. It works for a while but then SD asserts. 

    0> SDH:INFO:sd_ble_enable: RAM START at 0x20001fd0
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> :DEBUG:Advertising idle.
    0> :DEBUG:Fast advertising.
    0> APP_ERROR:ERROR:app_error_fault_handler, id: 0x1 pc: 0x1117C info: 0

    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
    switch (ble_adv_evt)
    {
    case BLE_ADV_EVT_FAST:
    {
    NRF_LOG_DEBUG("Fast advertising.\r\n");
    break;
    }
    case BLE_ADV_EVT_IDLE:
    {
    NRF_LOG_DEBUG("Advertising idle.\r\n");
    m_advertising = false;
    timer_extended_compare(APP_IDLE_TIME_MS);
    timer_start();
    break;
    }
    default:
    {
    break;
    }
    }
    }

    To start the advertising when idle timer timeout happens:

    static void timer_event_handler(nrf_timer_event_t event_type, void *p_context)

    {
    BaseType_t yield_req = pdFALSE;
    xTimerPendFunctionCallFromISR(timer_pend_func, NULL, (uint32_t)event_type, &yield_req);
    portYIELD_FROM_ISR(yield_req);
    }

    static void timer_pend_func(void *param1, uint32_t param2)
    {
    if((nrf_timer_event_t)param2 == NRF_TIMER_EVENT_COMPARE0)
    {
    uint32_t ret;
    if(!m_advertising)
    {
    ret = ble_control_adv_start();
    if(ret != NRF_SUCCESS)
    {
    // Failed to start advertising, retry again after configured time.
    timer_extended_compare(APP_RETRY_TIME_MS);
    timer_start();
    }
    }
    }
    }

    timer_extended_compare() and timer_start() are just wrappers that use nrf_drv_timer_extended_compare() and nrf_drv_timer_enable() functions. 

Related