Skip to main content
klaas
Associate
November 5, 2013
Question

NVIC_EnableIRQ() causes Hardfault

  • November 5, 2013
  • 5 replies
  • 2305 views
Posted on November 05, 2013 at 19:34

Hello,

I'm using a STM32-discovery Board equiped with a STM32F100RB. Till now all I'm trying to do is to call the Interrupt-Handler of TIM3. But when calling NVIC_EnableIRQ(TIM2_IRQn) the programm is always running into the Hardfault_Handler.

Is there anybody who knows the reason for this behaviour?

thanks, Klaas.
    This topic has been closed for replies.

    5 replies

    frankmeyer9
    Associate III
    November 5, 2013
    Posted on November 05, 2013 at 20:45

    Till now all I'm trying to do is to call the Interrupt-Handler of TIM

    3

    . But when calling NVIC_EnableIRQ(TIM

    2

    _IRQn) the programm is always running into the Hardfault_Handler.

     

    A typo ?

    Check that you implemented the correct handler, and enabled the matching interrupt.

    Tesla DeLorean
    Guru
    November 5, 2013
    Posted on November 05, 2013 at 21:01

    GNU/GCC typically dumps all unhandled interrupts in the same spot, via weak linkage.

    With C++ watch for name mangling of the handler routines.

    A Hard Fault could occur due to missing handler (naming or linkage), or the routine depending on variables/pointers you haven't properly initialized prior to enabling the interrupt.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Fristedt.Jan
    Associate III
    November 6, 2013
    Posted on November 06, 2013 at 12:47

    Here is a good article that helped me:

    http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

    Slightly modified code:

    /**

      * @brief  C part of hard fault handler

      * @brief  http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

      * @param  pointer to stack frame

      * @retval none

      * @date   2013-10-07

      */

    void irqGetStackFrame(uint32_t *stackframe)

    {

      StackR0 = stackframe[0];

      StackR1 = stackframe[1];

      StackR2 = stackframe[2];

      StackR3 = stackframe[3];

      StackR12 = stackframe[4];

      StackLR = stackframe[5];

      StackPC = stackframe[6];

      StackPSR = stackframe[7];

      for(;;) {

      }

    } /* irqGetStackFrame */

    /**

      * @brief  assembler part of hard fault handler

      * @brief  http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

      * @param  none

      * @retval none

      * @date   2013-10-07

      */

    void HardFault_Handler(void)

    {

      __asm volatile

        (

         '' tst lr, #4                    \n''

         '' ite eq                        \n''

         '' mrseq r0, msp                    \n''

         '' mrsne r0, psp                    \n''

         '' ldr r1, [r0, #24]                \n''

         '' ldr r2, handler2_address_const            \n''

         '' bx r2                        \n''

         '' handler2_address_const: .word irqGetStackFrame    \n''

        );

    } /* HardFault_Handler */

    Here is what I do with undefined interrupt handlers, the number passed to the default hanler helps to find the problem:

    /**

      * @brief  default IRQ handler called by spurious interrupts

      * @param  irq: interrupt number

      * @retval none

      * @date   2013-10-04

      */

    static void defaultIrqHandler(int irq)

    {

      for (;;) {

      }

    } /* defaultIrqHandler */

    void NMI_Handler(void)

    {

      defaultIrqHandler(-9);

    }

    void MemManage_Handler(void)

    {

      defaultIrqHandler(-7);

    }

    void BusFault_Handler(void)

    {

      defaultIrqHandler(-6);

    }

    void UsageFault_Handler(void)

    {

      defaultIrqHandler(-5);

    }

    void SVC_Handler(void)

    {

      defaultIrqHandler(-4);

    }

    void DebugMon_Handler(void)

    {

      defaultIrqHandler(-3);

    }

    void PendSV_Handler(void)

    {

      defaultIrqHandler(-2);

    }

    #if 0 //defined somewhere else

    void SysTick_Handler(void)

    {

      defaultIrqHandler(-1);

    }

    #endif

    void WWDG_IRQHandler(void)

    {

      defaultIrqHandler(0);

    }

    void PVD_IRQHandler(void)

    {

      defaultIrqHandler(1);

    }

    void TAMP_STAMP_IRQHandler(void)

    {

      defaultIrqHandler(2);

    }

    void RTC_WKUP_IRQHandler(void)

    {

      defaultIrqHandler(3);

    }

    void FLASH_IRQHandler(void)

    {

      defaultIrqHandler(4);

    }

    void RCC_IRQHandler(void)

    {

      defaultIrqHandler(5);

    }

    etc...

    klaas
    klaasAuthor
    Associate
    November 7, 2013
    Posted on November 07, 2013 at 09:09

    Even if it's not the nicest solution I found one. I updated the CMSIS and Periph-Driver Package provided by ST from Version 3.3 to 3.4 and no it's working.

    thanks for the replies anyway!
    Tesla DeLorean
    Guru
    November 7, 2013
    Posted on November 07, 2013 at 13:21

    http://www.st.com/web/en/catalog/tools/PF257890

    Perhaps it relates to broader support for different chips, different interrupt vectors/implementation based on part/pre-processor defines.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..