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

Hard Fault Handler Issue

I have app_error_handler and HardFault_Handler defined - I have the WDT enabled.  My issue is if I trigger a hard fault:

// Enable divide by zero interrupt
//
SCB->CCR |= 0x10;

int HwTest = 10;
int HwDivisor = 0;
int HwTrigger = HwTest / HwDivisor;

I don't hit any break points in my code, the code stops at 0x000008c8 - the Softdevice handler.  My WDT does not fire. 

I'm trying to create a test case to catch and handle a hard fault in my code.  Any Ideas what I'm missing?  Thanks

  • Hello,

    Can you share some information on how you set up your watchdog timer?

    Do I understand you correctly if your question is why the watchdog timer is not kicking in and restarting the device when you are in the hardfault handler?

    BR,

    Edvin

  • Edvin - Yes that is one of the issue.  The other issue is - are there hard faults I can't catch at the app level?  I wasn't able to hit any handler breakpoints for divde by zero.

    /** @var s_channel_id
    * @brief Watchdog Channel Id
    */
    static nrf_drv_wdt_channel_id s_wdt_channel_id = 0;

    /** @brief WDT events handler.
    */
    void wdt_event_handler(void)
    {
    IspSystemReset_IncrementWatchdogResets();
    }

  • I missed that last part of my WDT code:

    nrf_drv_wdt_config_t config = {0};

    config.behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP;
    config.interrupt_priority = WDT_CONFIG_IRQ_PRIORITY;
    config.reload_value = SOFTWARE_WATCHDOG_TIMEOUT;

    err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
    ISP_STARTUP_ERROR_CHECK(err_code, ISP_STARTUP_LOG_ID_WDT_INIT);

    err_code = nrf_drv_wdt_channel_alloc(&s_wdt_channel_id);
    ISP_STARTUP_ERROR_CHECK(err_code, ISP_STARTUP_LOG_ID_WDT_CHANNEL);
    nrf_drv_wdt_enable();

  • Are you in a debug session while the hardfault handler is triggered? If so, try to change the config.behavior to NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT.

    If the issue is that the watchdog is not resetting when you are hitting a hardfault handler, then the hardfault handler itself will reset when you are not in a debug session. Also, with your current configuration the watchdog timer is halted in breakpoints. Try the RUN_SLEEP_HALT configuration, and see if that works. If not, please explain what sort of behavior you are looking for.

  • Edvin:  Sorry for the late reply, I have been busy on other bugs.  Basically I have a BLE test case that triggers a HardFault Error (divide by zero) on purpose so I can verify the HardFault handler works.  The tester stated he wasn't attached to a debugger but I will re-verify that setup. 

    Also it appears since I turned off the floating point hardware the "divide by zero" HardFault might be triggering a software error in the SoftDevice which is why it is going to 0x000008C8 instead of my handler.  I'm just trying to understand this IRQ routing better.

    I'm confused why the WDT isn't triggering a reset but it might be the JTAG emulator.  I will get more data.

    Is there another method to trigger a HardFault error?  I know you don't get this question very often but the "Divide by zero" test case is very useful for testing the HardFault logic, saving key data, registers etc.  I'm surprised how difficult it is to actually trigger one :).  I'm going to keep the code snippet that triggers my next real HardFault.   

Related