2017-01-19 12:19 PM
I'm compiling and running GPIO_EXTI example code for Nucleo-F767ZI board (on SW4STM32). The handler that blinks LED1 isn't connected and this matches what readme.txt says:
In this example:
- EXTI_Line15_10 is connected to PC.13 pin - when falling edge is detected on EXTI_Line15_10 by pressing User push-button, LED1 toggles onceOn STM32F767ZI-Nucleo:
- EXTI_Line15_10 is connected to User push-buttonSo, handler isn't set for the Nucleo board. When I push user button and pause (debugging) the program, it is then in default handler / infinite loop. All correct.
However, the program never goes beyond those lines of EXTI15_10_IRQHandler_Config(void):
/* Enable and set EXTI line 15_10 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);When I pause, I'm still in HAL_NVIC_EnableIRQ(), the program never returns to main() to do its infinite while() loop. As already said above, it however does react to user button, so the IRQ is correctly enabled.
I attach state after step-into the function, and step over its content. As it can be seen, the program forever runs that line (thread state says: 'Running: Step').
UPDATE: Here is the source code (main.c) of the GPIO_EXTI example, copied from official CubeMX package for F767 (V1.5.1):
Best regards,
Sebastian
#irq #examples #hang #exti_irqhandler #stm32cubemx-examples* #nucleo-f767ziSolved! Go to Solution.
2017-01-22 11:00 AM
Solution: empty while loop in main() has been optimized away to such extent that the debugger was showing last executed instruction in HAL_NVIC_EnableIRQ(). So it looked like if program was stuck in that call. Adding a volatile variable to the loop revealed that everything is fine.
2017-01-19 01:22 PM
The Cortex-Mx processors need you to clear the source of the interrupt, otherwise they will continually tail-chain and no foreground execution will occur. You need to review what your IRQHandler code is doing.
2017-01-20 06:19 AM
It's not my IRQHandler – this is an official example. There is no IRQHandler, but HAL_GPIO_EXTI_Callback(). I tried to add __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13) here:
static void EXTI15_10_IRQHandler_Config(void)
{ GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOC clock */
__HAL_RCC_GPIOC_CLK_ENABLE();/* Configure PC.13 pin as input floating */
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Pin = GPIO_PIN_13; HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);// The added line
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);
/* Enable and set EXTI line 15_10 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 1); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);}But still no change – program loops inside HAL_NVIC_EnableIRQ() as the screenshot shows.
Best regards,
Sebastian
2017-01-20 09:09 AM
Ok, but the screen shot really shows me nothing useful..
Right now I suspect it is off an an interrupt state, so you'd have to check the vector table and make sure it is binding with
EXTI15_10_IRQHandler properly. Could you show the code in
EXTI15_10_IRQHandler?
Put a break point in the Default Handler, EXTI15_10_IRQHandler and have the Hard Fault handler output diagnostic information if it gets there.
2017-01-20 09:40 AM
I did 'ack EXTI15_10_IRQHandler': and the only reference found is:
Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/gcc/startup_stm32f767xx.s
203: .word EXTI15_10_IRQHandler /* External Line[15:10]s */428: .weak EXTI15_10_IRQHandler429: .thumb_set EXTI15_10_IRQHandler,Default_HandlerI had no such function defined – working on verbatim copy of the GPIO_EXTI example (link to source at end of original post). So this explains why Default_Handler was being called.
The code expects this to happen:
void
HAL_GPIO_EXTI_Callback(
uint16_t
GPIO_Pin)
{
if
(
GPIO_Pin==
GPIO_PIN_13)
{
/* Toggle LED1 */
BSP_LED_Toggle
(
LED1)
;
}
}
But I think that this to happen, something has to be done to route interrupt not to EXTI15_10_IRQHandler(), but to HAL_GPIO_EXTI_IRQHandler(), because only there HAL_GPIO_EXTI_Callback() is called. Is there such thing? Does the example simply lack EXTI -> GPIO_EXTI binding, or what...?
When I define EXTI15_10_IRQHandler(), and blink LED there, it does blink, although toggling is unstable (sometimes it blinks just for a moment):
void EXTI15_10_IRQHandler(void)
{ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13); /* Toggle LED1 */ BSP_LED_Toggle(LED1);}Pausing after blink still shows that 'HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);' is the line being in execution.
Best regards,
Sebastian
2017-01-20 10:36 AM
I found the cause of half of this. The document 'Description of STM32F0xx HAL and Low-layer drivers' says:
When selecting EXTI mode with interrupt generation, the user must call HAL_GPIO_EXTI_IRQHandler() from stm32f0xx_it.c and implement HAL_GPIO_EXTI_Callback()
Turned out that somehow the file stm32f7xx_it.c (I have F7) didn't copy from the Examples directory into my CubeMX–prepared project. There was no EXTI15_10_IRQHandler() function in CubeMX generated file, and no HAL_GPIO_EXTI_IRQHandler() call in it.
Execution is still stuck at 'HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);' line, though (but handlers are called and the LED blinks).
Best regards,
Sebastian
2017-01-22 08:39 AM
Here is complete source code of the example. It's CubeMX project with files overwritten with those from GPIO_EXTI. Diff on the two projects reveals that everything possible is the same.
2017-01-22 10:53 AM
If possible, here would be my checklist: Has the port be selected for the EXTI properly? Exti 10..15 can be pa11, pb12, pc12, etc... Just make sure toggling the led does not trigger an exti by mistake...
Usually regardless of the code, it is very handy to put a breakpoint in the interrupt..
Then when the code stops, look at gpio and exti peripheral registers.
Remember the pending flag is cleared by clearing the right PR bit. Search for the code that does this and breakpoint onto it.
2017-01-22 11:00 AM
Solution: empty while loop in main() has been optimized away to such extent that the debugger was showing last executed instruction in HAL_NVIC_EnableIRQ(). So it looked like if program was stuck in that call. Adding a volatile variable to the loop revealed that everything is fine.