[Solved] STM32F4 ISR Crash/freeze

Hi Guys,

This is outside the typical maker space, and some may call me foolish for trying to do this, but learning the basics of STM32s without the ST abstractions, in my own time through the excellent series of guides by Vivonomicon. I’m currently learning interrupts, but my program seems to trigger a SIGTRAP fail when the interrupt fires.

The code consists of main.c for the main loop and setup code, and nvic.c for holding the ISRs. There are a few header files for the volatile led_on variable and pin constants, It’s running on an STM32413ZH Nucleo-144 board (I plan to use an 8080 LCD soon). All it does is watch the global led_on variable in the main loop, and on a rising edge on the on-board button (PC13) it’ll toggle this variable (or at least that’s what it’s supposed to do)

// main.c
#include "main.h"

int main(void){
  GPIOB->MODER = 0x1; // set Pin 0 to output mode
  // GPIOC is already in all input mode

  GPIOB->PUPDR = 0x0;
  GPIOB->OTYPER = 0x0;

  // uint8_t button_down = 0;
  RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable system configuration peripheral
  SYSCFG->EXTICR[3] &= ~(SYSCFG_EXTICR4_EXTI13_Msk); // Turn off all bits in EXTICR4 for pin 13 in all GPIO registers
  SYSCFG->EXTICR[3] |= (SYSCFG_EXTICR4_EXTI13_PC);  // Turn on the relevant bits for bank C
  EXTI->IMR |= (1 << BUTTON_PIN); // Enable button's EXTI line
  EXTI->FTSR &= ~(1 << BUTTON_PIN); // Disable falling edge trigger (button release)
  EXTI->RTSR |= (1 << BUTTON_PIN); // Enable rising edge trigger

  NVIC_SetPriority(EXTI15_10_IRQn, 0x03);

  while (1) {
    if (led_on) {
      GPIOB->ODR |= (1 << LED_PIN);
    else {
      GPIOB->ODR &= ~(1 << LED_PIN);
// nvic.c
#include "nvic.h"

void EXTI15_10_IRQHandler(void){
  if (EXTI->PR & (1 << BUTTON_PIN)) {
    // Clear the EXTI status flag.
    EXTI->PR |= (1 << BUTTON_PIN);
    // Toggle the global 'led on?' variable.
    led_on = !led_on;

void HardFault_Handler(void)
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)

This sequence is press button > sitgtrap pauses gdb > backtrace shows the above. Looks like it calls my ISR, but then there’s an unknown error handler in there afterwards?

If anyone is a wizard at these sorts of thing, or has some pointers for me to check, that’d be greatly appreciated! If there’s any part of my code you need explained, I’m sure I’d love the rubber duck experience :smiley: I posted this on the ST forum, but they’ve been unresponsive so far. If there’s a better place for this question, I’m happy to be redirected.

Keen to get to the bottom of this one!


Code .zip attached
interrupt problems.zip (194.0 KB)


Are you debouncing the button? The trap could be for interrupt queue overflow or system stack overflow on multiple interrupts, or there might be a default trap for ISR reentrancy. Do you have to clear the interrupt at the start of the ISR, or is that looked after by nvic? Do you have to mark the end of the ISR so that the appropriate RET is generated, or is that looked after by nvic?


Hi Jeff,

First off, excellent advice, those are all things I had not considered. Thank you!

Good point, I’ll remember this for next time, but unfortunately the error also occurs when the interrupt is configured to fire on a rising edge (button released, it has a pullup)

Apparently the M3/4 cores block all interrupts of the same or lower priority while the current ISR is executing, so it looks like I’m protected from that.

OK, looks like some stuff for me to check! I was hoping to disassemble my ISR, but it looks like it wasn’t making it into main.elf!. Someone on the ST forum suggested I put nvic.c into my makefile, instead of linking/compiling it.

I might be getting closer to a solution! I’ll see if I can look into why my code isn’t making it in, if you have any suggestions, lemme know.

EDIT: The thread on the ST forum has finally gotten some traction, and they’ve found that the ST and home-made linker and vector table disagree with each other. Link here - I’m fixing that up now and we’ll see if that does it


Hi James

I think switches tend to “bounce” both ways. That is both activation and release.
Cheers Bob


Hi All,

Yep, that did it, it works now :smiley:

I really need to be careful grabbing bits of code from here and there…

Now on to timers!