cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_GPIO_EXTI_Rising_Callback or EXTI0_1_IRQHandler

OHaza.1
Associate III

Hi, is there a reason to implement the HAL function over simply running code inside the IRQ handler.

In my current case I only am incrementing a counter and do not need to demux the line, so I presume not this time, but if I was doing something more involved.

Thanks Oliver

8 REPLIES 8
TDK
Guru

Convenience.

If you have multiple interrupts, HAL will call HAL_GPIO_EXTI_Rising_Callback for all of them and you can locate all of your code in the same place. Whereas if you put your code in the actual IRQ handler, you would need to duplicate code in each handler.

If you feel a post has answered your question, please click "Accept as Solution".

Cube/HAL will check and clear the interrupt source for you.

JW

Merging together all of the EXTI lines in a single function is not a convenience, but a problem because in that common callback function one has to sort out all of them and call the next level handlers from other software modules anyway.

I've found this approach to provide a good balance of convenience and performance:

void EXTI3_IRQHandler(void)
{
	if (EXTI->PR1 & EXTI_PR1_PIF3) {
		EXTI->PR1 = EXTI_PR1_PIF3;
 
		EXTIHandler_BTNx(BSP_BTN_LEFT);
	}
}
 
void EXTI9_5_IRQHandler(void)
{
	uint32_t rPR1 = EXTI->PR1;
	EXTI->PR1 = rPR1 & (EXTI_PR1_PIF6 | EXTI_PR1_PIF5);
 
	if (rPR1 & EXTI_PR1_PIF6) {
		EXTIHandler_MOTOR_DIAG();
	}
	if (rPR1 & EXTI_PR1_PIF5) {
		EXTIHandler_BTNx(BSP_BTN_RIGHT);
	}
}

Put this code in a BSP for the specific board and call from it the functionally specific handlers from other software modules. The "inconvenient and excess" code is just the lines 4 and 12-13, but those are trivial.

Looks like it has the potential to clear and miss an interrupt source

This might be safer

EXTI->PR1 = (EXTI_PR1_PIF6 | EXTI_PR1_PIF5) & rPR1;

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

But that's not exactly difficult, and doing all the processing in the IRQ Handler is probably clearer and more transparent. And can be limited to the actual sources rather than the kitchen sink approach HAL/Cube example frequently employ.

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

Right, I figure ideally it's best to do the functionality manually, i've gone with HAL_GPIO_EXTI_Rising_Callback in the end, kind of need rapid and reliable right now, although this means I now have to demux in the function whereas in the IRQ handler I wouldn't have to as the two interrupts would have their own.. somewhat unfortunate side effect of HAL.

> although this means I now have to demux in the function whereas in the IRQ handler I wouldn't have to as the two interrupts would have their own.. somewhat unfortunate side effect of HAL.

Eh, a lot of the EXTI interrupt handlers are shared so you may need to demux anyway. For example, the EXTI9_5_IRQHandler handler above or EXTI15_10_IRQHandler.

If you feel a post has answered your question, please click "Accept as Solution".

Indeed it can! Thanks! Somehow that shared line case slipped through. I fixed and expanded the original post so that people do not copy a broken example.

Well, this just reassures two things again and again:

  1. If those interrupts are slow and non-critical, no amount of testing will reveal such type of bugs. Dijkstra is right.
  2. My code is already fixed. It took me 5 minutes. Similar bugs (clearing interrupt after the callback) in HAL typically takes ST at least a year to fix. I looked for the same bug in old SPL based examples - of course it's there also. So in this case it's 15 years and counting.