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

What could explain a HardFault when entering in critical region?

Hello,

We are developing an application which is using the app_scheduler (especially to put events etc.)

It seems that sometimes (very rarely) we detected a Hard Fault when the app_scheduler is calling the CRITICAL_REGION_ENTER() macro (into the app_scheduler.c). We have retrieved core registers when the panic appears:

  • The program counter pointed to "sd_nvic_critical_region_enter" from sdk/import/s110_nrf51822/include/nrf_soc.h line 474 where we can find the supervisor call in order to disable irq.
  • IPSR = 0x3 --> HardFault

Any ideas about what could induce this hard fault?

Thx!

  • Since it looks from what you've posted that the hardfault is happening at the critical region enter (not inside the softdevice ie not a softdevice bug) then it seems it's happening at the svc() call. The only two reasons I know of that an svc() call will go to hardfault are if it's executed

    1. from a higher interrupt state, SVC() in the softdevice is a level 2 interrupt, so if it's called from a level 0 or 1 interrupt it will hardfault
    2. It's called when interrupts are disabled, ie PRIMASK is 1.

    Don't know how you are getting into one or other of those states, if you have the registers on the panic you should be able to figure out whether it's in thread or handler mode, what the current interrupt priority is if in handler mode and whether PRIMASK is or is not 1 and confirm that.

    I can't think of anything else.

  • Hello RK,

    Thanks a lot for your quick answer!

    About the first reason, I think this is handled by the CRITICAL_REGION_ENTER() macro because we won't disable IRQs when the current interrupt priority is HIGH =1. I don't see any app irq priority equal to 0, is it possible?

    I did a simple test, consisting to call two CRITICAL_REGION_ENTER, and I got the same panic trace. So it looks like we try to disable irq whereas it's already done. I will double check in our SW where it could happen.

    Thx again.

  • Check if you are using APP_TIMER and if you have set RTC1 interrupt handler priority to APP_HIGH, then like RK said it will cause an hardfault in app_scheculer

    below m_evt_schedule_func = app_timer_evt_schedule (set in APP_TIMER_INIT macro)

    RTC1_IRQHandler->timer_timeouts_check()->timeout_handler_exec->m_evt_schedule_func->app_sched_event_put->CRITICAL_REGION_ENTER
    
  • Hello Aryan,

    Thanks for your comment.

    Yes we are using the app_timer and the RTC1 IRQ is always set to LOW.

    But, actually, we have modify the app_timer in order to save RAM consumption, and I found the issue: In our RTC1_IRQHandler, we add CRITICAL_REGION_ENTER when calling "timer_timeouts_check()", so when there is a task to execute, we will perform another CRITICAL_REGION_ENTER in the app_scheduler.

    You routed me to the issue ;) Thx!

  • good to know, can you please accept the right answer so that we can close this case.

Related