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 Reply Children
  • I ran the debug variant of the bootloader project(pca10040_uart_debug), and here is the log of the bootloader.

    00> <info> app: Inside main
    00>
    00> <debug> app: In nrf_bootloader_init
    00>
    00> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    00>
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00>
    00> <debug> nrf_dfu_settings: Using settings page.
    00>
    00> <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    00>
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00>
    00> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    00>
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00>
    00> <debug> app: Enter nrf_bootloader_fw_activate
    00>
    00> <info> app: No firmware to activate.
    00>
    00> <debug> nrf_dfu_validation: CRC check of app failed. Return 1
    00>
    00> <debug> app: App is valid
    00>
    00> <warning> nrf_dfu_settings: No additional data erased
    00>
    00> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    00>
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00>
    00> <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
    00>
    00> <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0
    00>

     

  • Do you have any logs from your application as well?

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

    From your "NRF_LIBUARTE_ASYNC_DEFINE", you seem to be using RTC instance 0. This is used by the SoftDevice as well. Try using RTC instance 2 instead.

  • The only log that I get in my application is the one that I wrote

    <info> app: inside app main

    the other instance of logging before crushing is in the function nrf_drv_clock_init(), which is not getting processed even if I call NRF_LOG_FLUSH() or NRF_LOG_FINAL_FLUSH()

    but the returned value of nrf_drv_clock_init() passes the APP_ERROR_CHECK  

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

    From your "NRF_LIBUARTE_ASYNC_DEFINE", you seem to be using RTC instance 0. This is used by the SoftDevice as well. Try using RTC instance 2 instead.

    I changed the RTC instance to 2, also changed the timer instance to 3, but the problem still persists.

    Is it possible that the address of the modules in use are misplaced in ram? 

    EDIT::

    So I stumbled across bunch of parsing errors in output Source Navigator, which neither were showing in Target tab, nor they were indicated in any way during build, and all of these errors are complaining about "unknown register name 'vfpcc' in asm" in the cmsis_gcc.h header. 

    Which according to this https://devzone.nordicsemi.com/f/nordic-q-a/35481/source-navigator-in-segger-embedded-studio-reports-unknown-register-name-vfpcc-in-asm

    is not an issue

    However I include this for you to have full information regarding the issue.

  • Hi,

    Does it passes nrf_drv_clock_lfclk_request() as well?

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

    ...

    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.

  • 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);
    }

Related