Call to sys_reboot() on nRF52840 causes hard fault

Currently on SDK v2.3.0 but this problem has persisted no matter the SDK version. Here's the fault info.

[00:00:34.898,223] <err> mpsl_init: MPSL ASSERT: 112, 2195
[00:02:03.002,807] <err> os: ***** HARD FAULT *****
[00:02:03.002,807] <err> os: Fault escalation (see below)
[00:02:03.002,838] <err> os: ARCH_EXCEPT with reason 3

[00:02:03.002,838] <err> os: r0/a1: 0x00000003 r1/a2: 0x00000000 r2/a3: 0x000000bf
[00:02:03.002,838] <err> os: r3/a4: 0x00000000 r12/ip: 0x20001918 r14/lr: 0x00000000
[00:02:03.002,868] <err> os: xpsr: 0x61000018
[00:02:03.002,868] <err> os: Faulting instruction address (r15/pc): 0x0002caf8
[00:02:03.002,899] <err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
[00:02:03.002,929] <err> os: Fault during interrupt handling

[00:02:03.002,960] <err> os: Current thread: 0x20002d18 (unknown)
[00:02:04.186,157] <err> fatal_error: Resetting system

I have CONFIG_REBOOT=y listed in the prj.conf file. I try to step into sys_reboot and it immediately jumps to arch_irq_lock and faults. I look through the sample projects that reboot and I don't see anything that I'm missing in the prj.conf. Not sure what to think.

Any incite would be appreciated.

  • I see from the log that there are repeated resets, but is it still so that there is a long delay between each of them (you wrote  about 2 minutes, 30 seconds)? I wonder what happens during this time...

    Once I enter sys_reboot() or NVIC_SystemReset() it hangs for 2 minutes, 30 seconds. Chances are the fault dog is resetting the chip.

    Can you read, print and clear the RESETREAS register

    Yep. This is all I got from it.
    [00:00:00.000,244] \033[0m<inf> MAIN: Application soft reset detected

    Are you testing on your custom HW?

    Yes.

    If so, can you describe it?

    Here's the schematic.

  • Are you able to reproduce this on a DK? If so, can you upload a minimal project that reproduce it here so that I can test on my end?

  • Are you able to reproduce this on a DK?

    no. Works as expected on a DK and I tried it on the 3 that I have.

  • I found this ticket and it was the solution to the problem which is a bug in the bootloader. Who would have thought? I removed all support for Bootloader and DFU and low and behold, rebooting works. Now I just need to figure out a work around.
    sd_nvic_System_Reset() causes my application to hang until WDT timeout 

    Thanks for all your help!

  • Hi,

    Good catch! I did not think about it, but this is a known issue which is only seen after doing a soft reset with the WDT enabled and using the LFRC as low frequency clock source.

    The workaround is to modify timer_init() from components/libraries/bootloader/nrf_bootloader_dfu_timers.c like this (notice the commented out lines):

    static void timer_init(void)
    {
        static bool m_timer_initialized;
    
        if (!m_timer_initialized)
        {
            // if (!nrf_clock_lf_is_running())
            // {
                nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
            // }
    
            nrf_rtc_event_clear(RTC_STRUCT, NRF_RTC_EVENT_TICK);
            nrf_rtc_event_clear(RTC_STRUCT, NRF_RTC_EVENT_COMPARE_0);
            nrf_rtc_event_clear(RTC_STRUCT, NRF_RTC_EVENT_COMPARE_1);
            NRFX_IRQ_PRIORITY_SET(RTC_IRQn, 5);
            NRFX_IRQ_ENABLE(RTC_IRQn);
            nrf_rtc_prescaler_set(RTC_STRUCT, RTC_PRESCALER);
            nrf_rtc_task_trigger(RTC_STRUCT, NRF_RTC_TASK_CLEAR);
            nrf_rtc_task_trigger(RTC_STRUCT, NRF_RTC_TASK_START);
            nrf_rtc_int_enable(RTC_STRUCT, RTC_INTENSET_OVRFLW_Msk);
    
            m_timer_initialized = true;
        }
    }

    The reason this is needed is that when the WDT is running, this will force the LFRC to continue to run during and after a soft reset. And the LFCLKSTAT register that is checked by nrf_clock_lf_is_running() will indicate that the clock is running.  However, the clock is only routed to the WDT in this case, so it needs to be started by triggering the LFCLKSTART task. So the if statement is never needed, but only cause problems in this specific case.

    Edit: Apparently I forget a lot of things during a weekend. The post you linked to was about the nRF5 SDK bootloader, but I remember now that you are using the nRF Connect SDK, which is completely different (using MCUBoot as a bootloader). There might still be an issue here though, but I am not aware of it, and it does not seem like you are using a Watchdog?

Related