Proper way to handle external interrupts

I am using an STM32F207 platform and the ST HAL drivers. One of the I2C interfaces is connected to a Microchip MCP23017 GPIO expander. The GPIO expander has its interrupt output pin connected to a GPIO pin on the STM32F207.

When the interrupt is triggered the HAL calls HAL_GPIO_EXTI_IRQHandler() which clears the interrupt within the microcontoller and then calls HAL_GPIO_EXTI_Callback().

Should HAL_GPIO_EXTI_Callback() do the actual work of reading the GPIO expander to determine what caused the interrupt and then pass that information to a FreeRTOS task to deal with it or should HAL_GPIO_EXTI_Callback() simply wake up a FreeRTOS task and have the task read the GPIO expander?


Generally the best practice is to signal a task to do the I2C comms.

Hi Jeff,

Is there an example of this anywhere?


There are examples of different ways of signaling tasks from interrupts on various documentation pages, such as and in the free to download (if a little out of date) book.

The book Richard mentioned is here. Chapter six should help a bunch.

I have put the contents of the vANInterruptHandler() function from the RTOS Task Notification As Counting Semaphore example into HAL_GPIO_EXTI_Callback().

The first time the hardware interrupt fires I am getting an assert thrown in FreeRTOS/portable/GCC/ARM_CM3/port.c at line 686.

            /* The following assertion will fail if a service routine (ISR) for
             * an interrupt that has been assigned a priority above
             * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
             * function.  ISR safe FreeRTOS API functions must *only* be called
             * from interrupts that have been assigned a priority at or below
             * ...
             * The following links provide detailed information:
             * */
            configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

I’ve checked the referenced page that talks about Cortex-M3 and M4 and have confirmed that the HAL_Init() function is calling NVIC_PriorityGroupConfig() as per the big red warning!

I’m guessing this is probably down to the priority the handling task is being created with (uxPriority is set to 2 when the handling task is created with xTaskCreate().


Ignore me! The hardware interrupt was being enabled with HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); which was never going to work well!