Hardware IRQs completely block thread execution on STM32L4

To test my I2C SMBus driver for STM32 I use FreeRTOS notifications to test that I2C events (ISRs) are triggered in the right order and within expected time frames. My test suite works really well but there is one minor issue which makes me believe that I do something wrong. During tests execution ISR completely block the thread which blinks onboard LED. Not a big deal, but it is interesting. The thread has osPriorityRealtime, I2C events have priority 15 (the lowest) and LED still stops blinking during long I2C transmissions. This got me thinking; is it even possible for the FreeRTOS thread to interrupt ISR? Maybe it is not when FreeRTOS task scheduler running on STM32 is clocked by SysTick timer which interrupt has priority 15 (the lowest). At lest this is the default CubeMX configuration which probably should not be modified. Am I missing something?

To the best of my knowledge, A FreeRTOS task will not be scheduled while an ISR is executing. However ISRs may sometimes nest. You might minimize ISR execution time, possibly changing I2C parameters to balance between latency and throughput.

I am not aware of any microcontroller architectures that would allow isrs to be interrupted by anything than higher prioritized isrs.

Tomasz, it is by design that lengthy communications/computations/whatever in isrs will starve lower priority threads of execution. To counter that effect, you may want to experiment with DMA supported communications.

ISRs execution handling is short, but there are lots of them since the transmission speed is high. Usually before one IRS finishes another one is already waiting. I know because often next IRQ flag gets set before current one finishes.
Maybe, at least some times, RTOS scheduler should be able to interrupt ISR, that means, have higher priority? Is such pattern allowed?

No, interrupts can never be interrupted (again, unless by a higher pri isr which will not solve your problem), at best masked, but at the risk of losing some.

If offloading isr activity to the hardware (again, for example by using DMA) is no option for you, you could try to delegate some early character processing from the application to the isr.

The best solution, at least in my situation, would be such RTOS configuration where high priority threads/tasks actually could interrupt or temporarily stop lower priority hardware events from firing. I do not mind if tested communication slows down a bit, I do not worry about loosing events. Those I2C events are level-triggered so STM32 NVIC will keep triggering them again and again until they are handled and corresponding event flag is reset or some other condition is met. Otherwise, I think I have to implement some throttle - e.g. disable I2C events every 1ms for a moment to let RTOS do its stuff, but does not it sound odd? Intuition tells me that there should be a better way.

In that case you could suppress interrupts from your task, either by disabling them on the device level or by claiming the critical section (assuming your isr runs on a priority max_syscall).

You coul also delegate your high pri computation to a Software interrupt handler running at a higher priority.

Finally, does your I2C need to be interrupt driven, or can you address it through, say, polling?

Thanks, it has to be IRQ-driven, even if DMA is used, perhaps in the next version. Here RTOS serves just as a convenient test environment. The driver likely will be used in a system without RTOS, just driven by IRQs - many of them, some timer-triggered to implement quasi-threads, but no need for RTOS. I call it true real time system :slight_smile: