2021-06-27 04:56 AM
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.
The 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
where 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.
2021-06-27 06:21 AM
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?
2021-06-27 06:30 AM
Look at disassembly at faulting instruction, and processor's general registers
2021-06-27 06:37 AM
Clearing wrong source
2021-06-27 06:44 AM
>>Or is this a stack overflow?
Possibly, look at the SP
More generally mark the stack so you can see maximal usage over time
2021-06-27 06:46 AM
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!
2021-06-27 07:04 AM
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!