cancel
Showing results for 
Search instead for 
Did you mean: 

EXTI Interrupt Handler throwing HardFault for one MCU, but not for other MCU

Lars Beiderbecke
Senior III

I have two custom boards with one STM32F746 each. Both MCUs run identical code (in different projects with potentially different configuration).

One MCU runs as expected, but the other MCU throws a HardFault as soon as MX_NVIC_Init() enables EXTI interrupts.

0693W00000Bc67cQAB.pngThe EXTI1 handler contains this code

void EXTI1_IRQHandler(void)
{
  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
  if (GPIOA->IDR & 0x0002) { 
    EXTI->PR = 1;
    (void) EXTI->PR; // wait for PR bit being cleared
  // ...
}

where the IDE points to the line with the if statement for the HardFault.

The fault registers show these values

0693W00000Bc681QAB.pngwhere I've seen values of 0x1, 0x10000 and 0x80000 for CFSR.

So what exactly is throwing the HardFault, given that the second MCU doesn't? At first I thought of the 4x16 SDRAM, but I've enabled byte-access for both MCUs.

6 REPLIES 6
Lars Beiderbecke
Senior III

The assembly for the EXTI1 handler is this (the address is due to the location in ITCM RAM):

000001bc <EXTI1_IRQHandler>:
 1bc:   4bad            ldr     r3, [pc, #692]  ; (474 <_Min_Stack_Size+0x74>)
 1be:   2102            movs    r1, #2
    __HAL_RTC_ALARMA_DISABLE(hrtc);
 1c0:   4aad            ldr     r2, [pc, #692]  ; (478 <_Min_Stack_Size+0x78>)
 1c2:   b5f0            push    {r4, r5, r6, r7, lr}
 1c4:   6159            str     r1, [r3, #20]

I don't really see why a fault was triggered at address 0x1c0. Or is this a stack overflow?

Look at disassembly at faulting instruction, and processor's general registers

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
  1. if (GPIOA->IDR & 0x0002) {
  2. EXTI->PR = 1;

Clearing wrong source

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

>>Or is this a stack overflow?

Possibly, look at the SP

More generally mark the stack so you can see maximal usage over time

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Which source does it refer to? I was asking why NVIC_ClearPendingIRQ() didn't work, and got that answer.

The entire sequence looks like this:

EXTI->PR = 1;
    (void) EXTI->PR; // wait for PR bit being cleared
    NVIC_ClearPendingIRQ(EXTI0_IRQn);
    NVIC_EnableIRQ(EXTI0_IRQn);

So would that still be incorrect? And why does the other MCU not complain about this?

EDIT: For clarification, EXTI1 enables EXTI0!

Lars Beiderbecke
Senior III

Oh ******. While the code between both projects is identical, main.c isn't because of differences in peripherals. And of course in the failing project, I forgot to copy the contents of ITCM RAM from RAM to ITCM RAM. No wonder I get a fault the first time the program enter ITCM RAM! :pile_of_poo:

*sigh*

Tesla, thanks for your input, though!