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

Go into hardfault "NRF_BREAKPOINT_COND" while initialising

Hello developers,

I would like to combine BLE Central with USB HID. I am using the SDK example "BLE_Central_multilink", I can get signal from BLE modules.

Now I want to send data to PC through USB HID Protocol. I followed the example "usbd_hid_generic" and got finally no error from build.

However, the code go into hardfault while the initialising "err_code = nrf_drv_clock_init();" If I change the sequence, then from the other initialising.

If I debug it, this message is printed out "UNKNOWN FAULT at 0x0002DDE6".

If you help me to explain or solve the problem, I will very thank you.

I attatch my main code below

int main(void)
{
    // Initialize.

    log_init();
    timer_init();
    leds_init();
    buttons_init();
    power_management_init();
    ble_stack_init();
    gatt_init();
    db_discovery_init();
    lbs_c_init();
    ble_conn_state_init();
    scan_init();

    /* USB HID Intialization */
    ret_code_t err_code;
    static const app_usbd_config_t usbd_config = {
        .ev_state_proc = usbd_user_ev_handler
    };

    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);

    while(!nrf_drv_clock_lfclk_is_running())
    {
    } /* Waiting till running */

    //err_code = app_timer_init();
    //APP_ERROR_CHECK(ret);

    err_code = app_timer_create(&m_usb_hid_timer, APP_TIMER_MODE_REPEATED, data_transfer_timer_handler);
    APP_ERROR_CHECK(err_code);

    init_bsp();
#if NRF_CLI_ENABLED
    init_cli();
#endif
    printf("Hello USB!\n");
    err_code = app_usbd_init(&usbd_config);
    APP_ERROR_CHECK(err_code);

    printf("USBD HID generic example started\n");
    app_usbd_class_inst_t const * class_inst_generic;
    class_inst_generic = app_usbd_hid_generic_class_inst_get(&m_app_hid_generic);

    err_code = hid_generic_idle_handler_set(class_inst_generic, idle_handle);
    APP_ERROR_CHECK(err_code);

    err_code = app_usbd_class_append(class_inst_generic);
    APP_ERROR_CHECK(err_code);

    if(USBD_POWER_DETECTION)
    {
        err_code = app_usbd_power_events_enable();
        APP_ERROR_CHECK(err_code);
    }else
    {
        printf("No USB power detection enabled\r\nStarting USB now");
        app_usbd_enable();
        app_usbd_start();
    }

    // Start execution.
    printf("Multilink example started.\n");
    scan_start();

    for (;;)
    {
        
        idle_state_handle();
    }
}

Program information:

Segger Embedded Studio for ARM v5.50b

nRF52 SDK 17.0.2

Softdevice s140

codes based on PCA10056

Best regards

it0406

Parents
  • Hello,

    If I change the sequence, then from the other initialising.

    Could you elaborate on what you meant by this?

    If I debug it, this message is printed out "UNKNOWN FAULT at 0x0002DDE6".

    Could you confirm that you have DEBUG defined in your Preprocessor Definitions of the Common build configuration, as shown in the included image?

    This will make a detailed error message be written to your logger whenever a non-NRF_SUCCESS error code is passed to an APP_ERROR_CHECK.
    Please do this, and let me know what this error message says.

    Best regards,
    Karl

  • Could you elaborate on what you meant by this?

    I mean, I thought that there is the problem because of flow. For example, the clock should be initialized after timer initialization or before bluetooth low energy. I moved clock initialization between timer and ble initialization.

    Could you confirm that you have DEBUG defined in your Preprocessor Definitions of the Common build configuration, as shown in the included image?

    They are all defined like below:

    APP_TIMER_V2
    APP_TIMER_V2_RTC1_ENABLED
    BOARD_PCA10056
    CONFIG_GPIO_AS_PINRESET
    DEBUG
    DEBUG_NRF
    FLOAT_ABI_HARD
    INITIALIZE_USER_SECTIONS
    NO_VTOR_CONFIG
    NRF52840_XXAA
    NRF_SD_BLE_API_VERSION=7
    S140
    USBD_POWER_DETECTION

    I thought that the problem comes from the pin setting. I corrected all pin setting from PCA10056 to nRF52840 Feather which I am using. I got now interrupt while ble_stack_init() with the message. I initialized also log to print out error message, but it doesn't work. So I am just using printf function.

    HARD FAULT at 0x00032FE0
      R0:  0x2003FFAC  R1:  0x000287D9  R2:  0x20007BDC  R3:  0x00000001  R12: 0x20007B20  LR:  0x00033075  PSR: 0x01000000

    I have also some questions.

    Is there software flow diagram which I have to consider by programming?

    I set the configuration just like from ble_app_multilink and usbd_hid_generic examples. If I combine these two examples, should I set more memory segment?

    Memory Segment : FLASH RX 0x0 0x100000;RAM1 RWX 0x20000000 0x40000

    Best regards

    it0406

  • Hello again, it0406

    I just saw in your provided main code that you have a timer_init prior to your call to nrf_drv_clock_init - could you show me the contents of this timer_init function?

    it0406 said:
    They are all defined like below:

    Thank you for clarifying.

    If I debug it, this message is printed out "UNKNOWN FAULT at 0x0002DDE6".

    Could I also see the section of the code leading up to this error? I.e which line triggers this error, and what are the section of code being executed right before it?
    An unknown fault is usually caused by a uninitialized error code being passed to an APP_ERROR_CHECK, or if a value returned from a function is modified before being passed to an APP_ERROR_CHECK.

    it0406 said:
    I initialized also log to print out error message, but it doesn't work. So I am just using printf function.

    Which logger backend are you using? Please know that if you have RETARGET_ENABLED then your printf function will be routed to the UART, and so it will be unavailable to the logger.

    it0406 said:
    I set the configuration just like from ble_app_multilink and usbd_hid_generic examples. If I combine these two examples, should I set more memory segment?

    The SoftDevice will require some allocated memory, so you should use the memory configuration of the multilink example. In the case that too little memory is allocated to the SoftDevice it will tell you what to change the parameters to in the logger's output upon runtime failure.

    Best regards,
    Karl

  • Hello again, Karl

    Sorry about the late reply. I got the hardfault before. But now I get other hardfault result:

    HARD FAULT at 0x00032FE0
    R0: 0x2003FFAC R1: 0x000287D9 R2: 0x20007BDC R3: 0x00000001 R12: 0x20007B20 LR: 0x00033075 PSR: 0x01000000

    could you show me the contents of this timer_init function?

    This function has two lines like below:

    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }

    Could I also see the section of the code leading up to this error?

    The function is based on SDK (or just on Segger Embedded Studio?). The variable p_stack is not null. So goes into line 47, 

    void HardFault_c_handler(uint32_t * p_stack_address)
    {
        NRF_LOG_FINAL_FLUSH();
    
    #if (__CORTEX_M == 0x04)
    
    #ifndef CFSR_MMARVALID
      #define CFSR_MMARVALID (1 << (0 + 7))
    #endif
    
    #ifndef CFSR_BFARVALID
      #define CFSR_BFARVALID (1 << (8 + 7))
    #endif
    
        HardFault_stack_t * p_stack = (HardFault_stack_t *)p_stack_address;
        static const char *cfsr_msgs[] = {
            [0]  = "The processor has attempted to execute an undefined instruction",
            [1]  = "The processor attempted a load or store at a location that does not permit the operation",
            [2]  = NULL,
            [3]  = "Unstack for an exception return has caused one or more access violations",
            [4]  = "Stacking for an exception entry has caused one or more access violations",
            [5]  = "A MemManage fault occurred during floating-point lazy state preservation",
            [6]  = NULL,
            [7]  = NULL,
            [8]  = "Instruction bus error",
            [9]  = "Data bus error (PC value stacked for the exception return points to the instruction that caused the fault)",
            [10] = "Data bus error (return address in the stack frame is not related to the instruction that caused the error)",
            [11] = "Unstack for an exception return has caused one or more BusFaults",
            [12] = "Stacking for an exception entry has caused one or more BusFaults",
            [13] = "A bus fault occurred during floating-point lazy state preservation",
            [14] = NULL,
            [15] = NULL,
            [16] = "The processor has attempted to execute an undefined instruction",
            [17] = "The processor has attempted to execute an instruction that makes illegal use of the EPSR",
            [18] = "The processor has attempted an illegal load of EXC_RETURN to the PC, as a result of an invalid context, or an invalid EXC_RETURN value",
            [19] = "The processor has attempted to access a coprocessor",
            [20] = NULL,
            [21] = NULL,
            [22] = NULL,
            [23] = NULL,
            [24] = "The processor has made an unaligned memory access",
            [25] = "The processor has executed an SDIV or UDIV instruction with a divisor of 0",
        };
    
        uint32_t cfsr = SCB->CFSR;
        
        if (p_stack != NULL)    //Here, where the code meet the error
        {
            // Print information about error.
            NRF_LOG_ERROR("HARD FAULT at 0x%08X", p_stack->pc);
            printf("HARD FAULT at 0x%08X\n", p_stack->pc); 
            NRF_LOG_ERROR("  R0:  0x%08X  R1:  0x%08X  R2:  0x%08X  R3:  0x%08X",
                                 p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
                                 printf("  R0:  0x%08X  R1:  0x%08X  R2:  0x%08X  R3:  0x%08X",
                                 p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
            NRF_LOG_ERROR("  R12: 0x%08X  LR:  0x%08X  PSR: 0x%08X",
                                 p_stack->r12, p_stack->lr, p_stack->psr);
                                 printf("  R12: 0x%08X  LR:  0x%08X  PSR: 0x%08X",
                                 p_stack->r12, p_stack->lr, p_stack->psr);
        }
        else
        {
            NRF_LOG_ERROR("Stack violation: stack pointer outside stack area.");
        }
    
        if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk)
        {
            NRF_LOG_ERROR("Cause: BusFault on a vector table read during exception processing.");
        }
    
        for (uint32_t i = 0; i < sizeof(cfsr_msgs) / sizeof(cfsr_msgs[0]); i++)
        {
            if (((cfsr & (1 << i)) != 0) && (cfsr_msgs[i] != NULL))
            {
                NRF_LOG_ERROR("Cause: %s.", (uint32_t)cfsr_msgs[i]);
            }
        }
    
        if (cfsr & CFSR_MMARVALID)
        {
            NRF_LOG_ERROR("MemManage Fault Address: 0x%08X", SCB->MMFAR);
        }
    
        if (cfsr & CFSR_BFARVALID)
        {
            NRF_LOG_ERROR("Bus Fault Address: 0x%08X", SCB->BFAR);
        }
    
    #if defined(DEBUG)
    
        NRF_BREAKPOINT_COND;
    
     #endif // defined (DEBUG)
    
    #endif // __CORTEX_M == 0x04
    
        HardFault_process((HardFault_stack_t *)p_stack_address);
    }
    #endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)

    I sorted the codes below how it goes into hardfault.

    First of all, I got the error while ble_stack_init now. On this init function, it goes into nrf_sdh_enable_request in line 5. The function can run to the line 56 "ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);". While the function from Softdevice "SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));" in the file "nrf_sdm.h" runs, it leads up to hardfault like above. 

    static void ble_stack_init(void)    //in main.c
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();  //runs to here
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    /* And go inside the function in the other c file */
    ret_code_t nrf_sdh_enable_request(void)
    {
        ret_code_t ret_code;
    
        if (m_nrf_sdh_enabled)
        {
            return NRF_ERROR_INVALID_STATE;
        }
    
        m_nrf_sdh_continue = true;
    
        // Notify observers about SoftDevice enable request.
        if (sdh_request_observer_notify(NRF_SDH_EVT_ENABLE_REQUEST) == NRF_ERROR_BUSY)
        {
            // Enable process was stopped.
            return NRF_SUCCESS;
        }
    
        // Notify observers about starting SoftDevice enable process.
        sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLE_PREPARE);
    
        nrf_clock_lf_cfg_t const clock_lf_cfg =
        {
            .source       = NRF_SDH_CLOCK_LF_SRC,
            .rc_ctiv      = NRF_SDH_CLOCK_LF_RC_CTIV,
            .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
            .accuracy     = NRF_SDH_CLOCK_LF_ACCURACY
        };
    
        CRITICAL_REGION_ENTER();
    #ifdef ANT_LICENSE_KEY
        ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler, ANT_LICENSE_KEY);
    #else
        ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);    //Here, in this function
    #endif
        m_nrf_sdh_enabled = (ret_code == NRF_SUCCESS);
        CRITICAL_REGION_EXIT();
    
        if (ret_code != NRF_SUCCESS)
        {
            return ret_code;
        }
    
        m_nrf_sdh_continue  = false;
        m_nrf_sdh_suspended = false;
    
        // Enable event interrupt.
        // Interrupt priority has already been set by the stack.
        softdevices_evt_irq_enable();
    
        // Notify observers about a finished SoftDevice enable process.
        sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLED);
    
        return NRF_SUCCESS;
    }
    
    /* the section of the code leading up to the error in the header file nrf_sdm.h */
    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    Which logger backend are you using? Please know that if you have RETARGET_ENABLED then your printf function will be routed to the UART, and so it will be unavailable to the logger.

    I am using nrf_log_default_backends_init. You are right that the function is routed to the UART. I didn't see the detail.

    void nrf_log_default_backends_init(void)
    {
        int32_t backend_id = -1;
        (void)backend_id;
    
    #if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
        nrf_log_backend_uart_init();
        backend_id = nrf_log_backend_add(&uart_log_backend, NRF_LOG_SEVERITY_DEBUG);
        ASSERT(backend_id >= 0);
        nrf_log_backend_enable(&uart_log_backend);
    #endif
    }
    #endif

    The SoftDevice will require some allocated memory, so you should use the memory configuration of the multilink example. In the case that too little memory is allocated to the SoftDevice it will tell you what to change the parameters to in the logger's output upon runtime failure.

    Yes, there are return values which error or result I can get. But sorry, I can't see or don't know the return value. 

    /**@brief Enables the SoftDevice and by extension the protocol stack.
     *
     * @note Some care must be taken if a low frequency clock source is already running when calling this function:
     *       If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
     *       clock source will be started.
     *
     * @note This function has no effect when returning with an error.
     *
     * @post If return code is ::NRF_SUCCESS
     *       - SoC library and protocol stack APIs are made available.
     *       - A portion of RAM will be unavailable (see relevant SDS documentation).
     *       - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
     *       - Interrupts will not arrive from protected peripherals or interrupts.
     *       - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
     *       - Interrupt latency may be affected by the SoftDevice  (see relevant SDS documentation).
     *       - Chosen low frequency clock source will be running.
     *
     * @param p_clock_lf_cfg Low frequency clock source and accuracy.
                             If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
                             In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
     * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
     *
     * @retval ::NRF_SUCCESS
     * @retval ::NRF_ERROR_INVALID_ADDR  Invalid or NULL pointer supplied.
     * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
     * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
     * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
     */
    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    And I appreciate your help!

    Best regards

    it0406

Reply
  • Hello again, Karl

    Sorry about the late reply. I got the hardfault before. But now I get other hardfault result:

    HARD FAULT at 0x00032FE0
    R0: 0x2003FFAC R1: 0x000287D9 R2: 0x20007BDC R3: 0x00000001 R12: 0x20007B20 LR: 0x00033075 PSR: 0x01000000

    could you show me the contents of this timer_init function?

    This function has two lines like below:

    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }

    Could I also see the section of the code leading up to this error?

    The function is based on SDK (or just on Segger Embedded Studio?). The variable p_stack is not null. So goes into line 47, 

    void HardFault_c_handler(uint32_t * p_stack_address)
    {
        NRF_LOG_FINAL_FLUSH();
    
    #if (__CORTEX_M == 0x04)
    
    #ifndef CFSR_MMARVALID
      #define CFSR_MMARVALID (1 << (0 + 7))
    #endif
    
    #ifndef CFSR_BFARVALID
      #define CFSR_BFARVALID (1 << (8 + 7))
    #endif
    
        HardFault_stack_t * p_stack = (HardFault_stack_t *)p_stack_address;
        static const char *cfsr_msgs[] = {
            [0]  = "The processor has attempted to execute an undefined instruction",
            [1]  = "The processor attempted a load or store at a location that does not permit the operation",
            [2]  = NULL,
            [3]  = "Unstack for an exception return has caused one or more access violations",
            [4]  = "Stacking for an exception entry has caused one or more access violations",
            [5]  = "A MemManage fault occurred during floating-point lazy state preservation",
            [6]  = NULL,
            [7]  = NULL,
            [8]  = "Instruction bus error",
            [9]  = "Data bus error (PC value stacked for the exception return points to the instruction that caused the fault)",
            [10] = "Data bus error (return address in the stack frame is not related to the instruction that caused the error)",
            [11] = "Unstack for an exception return has caused one or more BusFaults",
            [12] = "Stacking for an exception entry has caused one or more BusFaults",
            [13] = "A bus fault occurred during floating-point lazy state preservation",
            [14] = NULL,
            [15] = NULL,
            [16] = "The processor has attempted to execute an undefined instruction",
            [17] = "The processor has attempted to execute an instruction that makes illegal use of the EPSR",
            [18] = "The processor has attempted an illegal load of EXC_RETURN to the PC, as a result of an invalid context, or an invalid EXC_RETURN value",
            [19] = "The processor has attempted to access a coprocessor",
            [20] = NULL,
            [21] = NULL,
            [22] = NULL,
            [23] = NULL,
            [24] = "The processor has made an unaligned memory access",
            [25] = "The processor has executed an SDIV or UDIV instruction with a divisor of 0",
        };
    
        uint32_t cfsr = SCB->CFSR;
        
        if (p_stack != NULL)    //Here, where the code meet the error
        {
            // Print information about error.
            NRF_LOG_ERROR("HARD FAULT at 0x%08X", p_stack->pc);
            printf("HARD FAULT at 0x%08X\n", p_stack->pc); 
            NRF_LOG_ERROR("  R0:  0x%08X  R1:  0x%08X  R2:  0x%08X  R3:  0x%08X",
                                 p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
                                 printf("  R0:  0x%08X  R1:  0x%08X  R2:  0x%08X  R3:  0x%08X",
                                 p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
            NRF_LOG_ERROR("  R12: 0x%08X  LR:  0x%08X  PSR: 0x%08X",
                                 p_stack->r12, p_stack->lr, p_stack->psr);
                                 printf("  R12: 0x%08X  LR:  0x%08X  PSR: 0x%08X",
                                 p_stack->r12, p_stack->lr, p_stack->psr);
        }
        else
        {
            NRF_LOG_ERROR("Stack violation: stack pointer outside stack area.");
        }
    
        if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk)
        {
            NRF_LOG_ERROR("Cause: BusFault on a vector table read during exception processing.");
        }
    
        for (uint32_t i = 0; i < sizeof(cfsr_msgs) / sizeof(cfsr_msgs[0]); i++)
        {
            if (((cfsr & (1 << i)) != 0) && (cfsr_msgs[i] != NULL))
            {
                NRF_LOG_ERROR("Cause: %s.", (uint32_t)cfsr_msgs[i]);
            }
        }
    
        if (cfsr & CFSR_MMARVALID)
        {
            NRF_LOG_ERROR("MemManage Fault Address: 0x%08X", SCB->MMFAR);
        }
    
        if (cfsr & CFSR_BFARVALID)
        {
            NRF_LOG_ERROR("Bus Fault Address: 0x%08X", SCB->BFAR);
        }
    
    #if defined(DEBUG)
    
        NRF_BREAKPOINT_COND;
    
     #endif // defined (DEBUG)
    
    #endif // __CORTEX_M == 0x04
    
        HardFault_process((HardFault_stack_t *)p_stack_address);
    }
    #endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)

    I sorted the codes below how it goes into hardfault.

    First of all, I got the error while ble_stack_init now. On this init function, it goes into nrf_sdh_enable_request in line 5. The function can run to the line 56 "ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);". While the function from Softdevice "SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));" in the file "nrf_sdm.h" runs, it leads up to hardfault like above. 

    static void ble_stack_init(void)    //in main.c
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();  //runs to here
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    /* And go inside the function in the other c file */
    ret_code_t nrf_sdh_enable_request(void)
    {
        ret_code_t ret_code;
    
        if (m_nrf_sdh_enabled)
        {
            return NRF_ERROR_INVALID_STATE;
        }
    
        m_nrf_sdh_continue = true;
    
        // Notify observers about SoftDevice enable request.
        if (sdh_request_observer_notify(NRF_SDH_EVT_ENABLE_REQUEST) == NRF_ERROR_BUSY)
        {
            // Enable process was stopped.
            return NRF_SUCCESS;
        }
    
        // Notify observers about starting SoftDevice enable process.
        sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLE_PREPARE);
    
        nrf_clock_lf_cfg_t const clock_lf_cfg =
        {
            .source       = NRF_SDH_CLOCK_LF_SRC,
            .rc_ctiv      = NRF_SDH_CLOCK_LF_RC_CTIV,
            .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
            .accuracy     = NRF_SDH_CLOCK_LF_ACCURACY
        };
    
        CRITICAL_REGION_ENTER();
    #ifdef ANT_LICENSE_KEY
        ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler, ANT_LICENSE_KEY);
    #else
        ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);    //Here, in this function
    #endif
        m_nrf_sdh_enabled = (ret_code == NRF_SUCCESS);
        CRITICAL_REGION_EXIT();
    
        if (ret_code != NRF_SUCCESS)
        {
            return ret_code;
        }
    
        m_nrf_sdh_continue  = false;
        m_nrf_sdh_suspended = false;
    
        // Enable event interrupt.
        // Interrupt priority has already been set by the stack.
        softdevices_evt_irq_enable();
    
        // Notify observers about a finished SoftDevice enable process.
        sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLED);
    
        return NRF_SUCCESS;
    }
    
    /* the section of the code leading up to the error in the header file nrf_sdm.h */
    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    Which logger backend are you using? Please know that if you have RETARGET_ENABLED then your printf function will be routed to the UART, and so it will be unavailable to the logger.

    I am using nrf_log_default_backends_init. You are right that the function is routed to the UART. I didn't see the detail.

    void nrf_log_default_backends_init(void)
    {
        int32_t backend_id = -1;
        (void)backend_id;
    
    #if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
        nrf_log_backend_uart_init();
        backend_id = nrf_log_backend_add(&uart_log_backend, NRF_LOG_SEVERITY_DEBUG);
        ASSERT(backend_id >= 0);
        nrf_log_backend_enable(&uart_log_backend);
    #endif
    }
    #endif

    The SoftDevice will require some allocated memory, so you should use the memory configuration of the multilink example. In the case that too little memory is allocated to the SoftDevice it will tell you what to change the parameters to in the logger's output upon runtime failure.

    Yes, there are return values which error or result I can get. But sorry, I can't see or don't know the return value. 

    /**@brief Enables the SoftDevice and by extension the protocol stack.
     *
     * @note Some care must be taken if a low frequency clock source is already running when calling this function:
     *       If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
     *       clock source will be started.
     *
     * @note This function has no effect when returning with an error.
     *
     * @post If return code is ::NRF_SUCCESS
     *       - SoC library and protocol stack APIs are made available.
     *       - A portion of RAM will be unavailable (see relevant SDS documentation).
     *       - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
     *       - Interrupts will not arrive from protected peripherals or interrupts.
     *       - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
     *       - Interrupt latency may be affected by the SoftDevice  (see relevant SDS documentation).
     *       - Chosen low frequency clock source will be running.
     *
     * @param p_clock_lf_cfg Low frequency clock source and accuracy.
                             If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
                             In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
     * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
     *
     * @retval ::NRF_SUCCESS
     * @retval ::NRF_ERROR_INVALID_ADDR  Invalid or NULL pointer supplied.
     * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
     * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
     * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
     */
    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    And I appreciate your help!

    Best regards

    it0406

Children
  • Hello again, it0406

    A common cause of ble_stack_init failing or the SoftDevice triggering a hardfault is that the application tries to access resources that are blocked or restricted by the SoftDevice. I see that your calls to the clock driver attempts to control the clock peripheral directly, rather than through the SoftDevice's API. This is likely a cause of the issue. Please see the note in the nrf_drv_clock_lfclk_request API documentation.
    Could I ask why you are requesting the lfclk here?
    The app_timer library will use an RTC instance, and so you may use the app_timer library to create timers for your application needs without risking to access restricted or blocked peripehrals.
    Try to remove these calls for direct clock control and let me know if it resolves your issue.

    Best regards,
    Karl

  • Hello Karl,

    I am new here with nRF5 SDK and SoftDevice. So I didn't know that there are init functions for SoftDevice and not for it. 

    Could I ask why you are requesting the lfclk here?

    I saw it in the usb hid generic example and thought that I need it to communicate a board with PC. 

    Do you mean these calls, nrf_drv_clock functions? I tried to remove nrf_drv_clock_init and nrf_drv_clock_lfclk_request and run my code again. It meets the same hardware fault yet. I could use app timer function for ble example. So I didn't remove it.

    The app_timer library will use an RTC instance, and so you may use the app_timer library to create timers for your application needs without risking to access restricted or blocked peripehrals.
    Try to remove these calls for direct clock control and let me know if it resolves your issue.

    As I know, I need a clock to transfer data between a board and computer. If the calls will not be used, does it mean that they are not important for usb hid protocol? Or does SoftDevice have functions like them? 

    Best regards,

    it0406

  • Hello,

    it0406 said:
    I am new here with nRF5 SDK and SoftDevice.

    Welcome! This is good for me to keep in mind when writing my answers, thanks for letting me know! :) 

    it0406 said:
    I saw it in the usb hid generic example and thought that I need it to communicate a board with PC. 
    it0406 said:
    As I know, I need a clock to transfer data between a board and computer. If the calls will not be used, does it mean that they are not important for usb hid protocol? Or does SoftDevice have functions like them? 

    Yes, the generic USB hid example does not use the SoftDevice, and so it must request the clocks manually. With the SoftDevice present the lfclk will always be running, and the hfclk will be running whenever needed by the SoftDevice or requested by the application.
    The requests for the hfclk should then instead be made through the SoftDevice API - so that the SoftDevice may accept or reject them - such as through the sd_clock_hfclk_request function. The SoftDevice needs to be in complete control of the clock operations since it needs to meet timing-critical deadlines to maintain its BLE connections.

    it0406 said:
    Do you mean these calls, nrf_drv_clock functions? I tried to remove nrf_drv_clock_init and nrf_drv_clock_lfclk_request and run my code again. It meets the same hardware fault yet. I could use app timer function for ble example. So I didn't remove it.

    Yes, it is the direct calls to control the clock peripheral that I am referring to.
    Indeed you do not need to remove the app_timer - you can safely use this for your application's lfclk needs.
    While this did not resolve this particular hardfault it is still good to have it checked out, as the issue would have come up down the line regardless.
    It could however still be that the hardfault is triggered by a read or write operation into SoftDevice controlled memory, for example.

    Could you open a debugger session and use breakpoints to figure out exactly how far in your program you are getting before the hardfault triggers? It would also be helpful if I could see the application code leading up to the hardfault triggering (not the hardfault handler, but your own application's code).

    Best regards,
    Karl

  • Hello Karl,

    Yes, the generic USB hid example does not use the SoftDevice, and so it must request the clocks manually. With the SoftDevice present the lfclk will always be running, and the hfclk will be running whenever needed by the SoftDevice or requested by the application.

    So if I understand, clock will be automatically running from SoftDevice if it is neccessary. I don't need to initialise and call the function. 

    Could you open a debugger session and use breakpoints to figure out exactly how far in your program you are getting before the hardfault triggers?

    Do you mean it maybe? The function "nrf_sdh_enable_request" will be called for ble_stack_init. I modified just main file and sdk_config.h from the example code. So I guess that it is possible because of SDK configuration, because I enabled and added some variables for usb hid. 

    If it would be helpful, I attach it as file.

    0675.sdk_config.h

    Best regards

    it0406

  • Hello again, it0406

    it0406 said:
    So if I understand, clock will be automatically running from SoftDevice if it is neccessary. I don't need to initialise and call the function. 

    This is correct, the SoftDevice will manage the peripherals as it needs.

    it0406 said:
    If it would be helpful, I attach it as file.

    Thank you. I notice in your sdk_config that you have configured the low frequency clock source to be XTAL (NRF_SDH_CLOCK_LF_SRC) - Could you confirm for me that the Feather module actually has an external LFCLK XTAL?
    Alternatively, you could try to set the clock configuration to the following:

    // <h> Clock - SoftDevice clock configuration
    
    //==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 1
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 16
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 1
    #endif
    
    // </h> 


    Best regards,
    Karl

Related