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!

Parents
  • 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
    
  • good observation sebastien, there is a limitation on how you use CRITICAL_REGION_xx macro. You cannot use it when softdevice is disabled and have the macro SOFTDEVICE_PRESENT defined in your project. you can just use below when you are not using softdevice

    static uint32_t m_in_critical_region = 0;
    
    void critical_region_enter(void)
    {
        __disable_irq();    
        m_in_critical_region++;    
    }
    
    void critical_region_exit(void)
    {
        m_in_critical_region--;    
        if (m_in_critical_region == 0)
        {
            __enable_irq();
        }
    }
    

    This code is also available in components\libraries\util\app_util_platform.c

Reply
  • good observation sebastien, there is a limitation on how you use CRITICAL_REGION_xx macro. You cannot use it when softdevice is disabled and have the macro SOFTDEVICE_PRESENT defined in your project. you can just use below when you are not using softdevice

    static uint32_t m_in_critical_region = 0;
    
    void critical_region_enter(void)
    {
        __disable_irq();    
        m_in_critical_region++;    
    }
    
    void critical_region_exit(void)
    {
        m_in_critical_region--;    
        if (m_in_critical_region == 0)
        {
            __enable_irq();
        }
    }
    

    This code is also available in components\libraries\util\app_util_platform.c

Children
No Data
Related