Skip to main content
Lars Beiderbecke
Senior III
June 27, 2021
Question

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

  • June 27, 2021
  • 6 replies
  • 2445 views

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.

This topic has been closed for replies.

6 replies

Lars Beiderbecke
Senior III
June 27, 2021

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?

Tesla DeLorean
Guru
June 27, 2021

>>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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
June 27, 2021

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

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

Clearing wrong source

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Lars Beiderbecke
Senior III
June 27, 2021

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
June 27, 2021

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!