Clock configuration fail in application with secure bootloader (uart mbr)

I am using nrf52832 with a custom board with no external crystal oscillator. As bootloader I use "secure_bootloader_uart_mbr" so I don't have softdevice. SDK is 17.1.0_ddde560

I have modified sdk_config.h of my application to use RC as LF clock source,
however I haven't added anything to sdk_config.h of the bootloader as it appears that the source is LF RC also there were no config lines related to the source of clock module in place already.


After bootloader starts my application I initialize the clock module, however my application crushes and causes the device to reset.

However when running application aloe without the bootloader everything works fine.

ret_code_t ret= nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);
    nrf_drv_clock_lfclk_request(NULL);

I assume the problem is some kind of interrupt because in the function nrfx_clock_lfclk_start() called by nrf_drv_clock_lfclk_request,  commenting the nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK) line lets the app to continue running. To be clear when uncommented the application fails 

when  CRITICAL_REGION_EXIT() is called in nrf_drv_clock_lfclk_request function.

The timer in bootloader seems to work, because it resets when in dfu mode for too long (around 2 min) 

void nrfx_clock_lfclk_start(void)
{
    NRFX_ASSERT(m_clock_cb.module_initialized);
    nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
    nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);

#if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
    nrfx_clock_anomaly_132();
#endif

    nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
}
 

void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
{
    ASSERT(m_clock_cb.module_initialized);

    if (m_clock_cb.lfclk_on)
    {
        if (p_handler_item)
        {
            p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
        }
        CRITICAL_REGION_ENTER();
        ++(m_clock_cb.lfclk_requests);
        CRITICAL_REGION_EXIT();
    }
    else
    {
        CRITICAL_REGION_ENTER();
        if (p_handler_item)
        {
            item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head,
                p_handler_item);
        }
        if (m_clock_cb.lfclk_requests == 0)
        {
            nrfx_clock_lfclk_start();
        }
        ++(m_clock_cb.lfclk_requests);
        CRITICAL_REGION_EXIT();//this call results in crush
    }

    ASSERT(m_clock_cb.lfclk_requests > 0);
}

I haven't made any changes to the bootloader source code except for public_key.c file, board definition and method of entering dfu mode.

Also I use a timer instance in libuarte if it is relevant.

NRF_LIBUARTE_ASYNC_DEFINE(libuarte,0,1,0,NRF_LIBUARTE_PERIPHERAL_NOT_USED,255,3);

I would appreciate any idea as what may cause this. 

Parents
  • Hi,

    After bootloader starts my application I initialize the clock module, however my application crushes and causes the device to reset.

    Could you test with the debug variant of the bootloader project(pca10040_uart_debug), and see if you get any errors or warnings printed in the log(Segger RTT logger backend)?

  • I assume you did this, NRF_SDH_CLOCK_LF_SRC to 0, NRF_SDH_CLOCK_LF_RC_CTIV to 16, NRF_SDH_CLOCK_LF_RC_TEMP_CTIV to 2, and NRF_SDH_CLOCK_LF_ACCURACY to 1. Perhaps also CLOCK_CONFIG_LF_SRC to 0.

    Yes, I have these settings in my application sdk_config

    Does it passes nrf_drv_clock_lfclk_request() as well?

    Are you able to debug, and figure out where it crashes?

    My application crashes inside nrf_drv_clock_lfclk_request() when it calles  CRITICAL_REGION_EXIT()

    here is the function below.

    void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
    {
        ASSERT(m_clock_cb.module_initialized);
    
        if (m_clock_cb.lfclk_on)
        {
            if (p_handler_item)
            {
                p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
            }
            CRITICAL_REGION_ENTER();
            ++(m_clock_cb.lfclk_requests);
            CRITICAL_REGION_EXIT();
        }
        else
        {
            CRITICAL_REGION_ENTER();
            if (p_handler_item)
            {
                item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head,
                    p_handler_item);
            }
            if (m_clock_cb.lfclk_requests == 0)
            {
                nrfx_clock_lfclk_start();
            }
            ++(m_clock_cb.lfclk_requests);
            CRITICAL_REGION_EXIT();//this call results in crush <=============
        }
    
        ASSERT(m_clock_cb.lfclk_requests > 0);
    }

  • 1) What happens when it crashes? Hardfault? or does it go to the app_error handler? Are you able to debug further after the crash?

    2) How does your main() function look like?

  • Here is what happens when it crushes, and you can see the main function here as well.

Reply Children
Related