Program does not get into hard fault exception when expected to do so
Hello,
If I understood correctly the a hard fault exception handler should catch all exceptions that do not have a specific handler that should execute when they are thrown. For example: if I enable button interrupts(say falling edge) and configure EXTI0 properly then I press the button(PA0) the cpu should try to find this ISR EXTI0_IRQHandler(). That works fine. But say I don't have that implemented. Shouldn't we end up in 'HardFault_Handler' then?
I'm using a STM32F446 controller from an STM32 nucleo board.
I wrote this code and tested if the code gets to 'EXTI0_IRQHandler' when I press the button. That works fine. I then commented out this ISR and expected the code to reach the hard fault handler isr when pressing the button. However that does not happen. The code stays stuck in the while loop. Please help me understand why that is happening and please correct me if I understood hard fault handlers in a wrong way. Thanks! This is the code:
#include "stm32f446xx.h"
#include "Board_LED.h"
#include "Board_Buttons.h"
// PA1(led) - output, push pull (SWITCH FROM BELOW(PA0) to PA1)
void leds_initialize()
{
RCC->AHB1ENR |= (1ul << 0); /* Enable GPIOA clock */
// configure pa1(the led)
GPIOA->MODER |= ( 1 << 2 );
GPIOA->MODER &= ~( 1 << 3 );
GPIOA->OTYPER &= ~( 1 << 1 );
// initially led is off
GPIOA->ODR &= ~(1 << 1);
}
// button(pa0)
void buttons_initialize()
{
// configure PA0(the button) - input/pull down
GPIOA->MODER &= ~( 1 << 0 );
GPIOA->MODER &= ~( 1 << 0 );
GPIOA->OTYPER &= ~( 1 << 0 );
GPIOA->PUPDR &= ~( 1 << 0 );
GPIOA->PUPDR |= ( 1 << 1 );
// configure the interrupt part
SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI0_PA; // enable PA0 as EXTI0(macro = 0x0000U)
EXTI->IMR |= ( 1 << 0 ); // interrupt request from line 0 is NOT MASKED
EXTI->RTSR &= ~( 1 << 0); // rising trigger disabled for external interrupt input line 0
EXTI->FTSR |= ( 1 << 0 ); // falling trigger enabled for external interrupt input line 0
/* ENABLE THE CORRESPONDING NVIC LINE WHERE EXTI0 LINE IS CONNECTED */
NVIC->ISER[0] |= ( 1 << EXTI0_IRQn );
}
int main(void)
{
leds_initialize();
buttons_initialize();
while(1)
{
}
return 0;
}
#if 0
void EXTI0_IRQHandler(void)
{
// Check if the pending bit for exti0 is really set before processing the interrupt
if( (EXTI->PR) & 0x01 )
{
EXTI->PR |= 1; // clear the bit
GPIOA->ODR ^= ( 1 << 1 ); // toggle the LED
}
}
#endif
#if 1
void HardFault_Handler(void)
{
EXTI->PR |= 1; // clear the bit
GPIOA->ODR ^= ( 1 << 1 ); // toggle the LED
}
#endif
Thank you for reading my post!


