cancel
Showing results for 
Search instead for 
Did you mean: 

Fastest IRQ response on STM32F04?

Martijn Jasperse
Associate II
Posted on March 10, 2018 at 06:36

Hi all,

I'm trying to respond to an IRQ in the fastest way possible on an STM32F04. Configuring a GPIO as EXTI works, but there's a ~200ns delay even at highest priority, presumably due to the overhead of the IRQ and calling the handler. The documentation suggests up to 12 clock cycles are required, which should be ~70ns at 168MHz?

I don't mind polling for the IRQ in my main loop - the micro isn't doing anything else, and this does work with very small delay (~20ns or so) provided the pin is configured as GPIO_INPUT and not as EXTI. However, the pulse width of the IRQ is only ~20ns so it sometimes misses it if I'm just reading the pin in a loop (~1 in 10). Given the short pulse I expect this to happen, but I want to know what alternatives I might have besides using some circuitry to extend the pulse duration.

I had the idea to use a timer as a counter for the IRQ pulses, which I can then check in my main loop. If I received 1 count, then I perform the required behaviour, and if I see 2+ counts then obviously I have missed an IRQ but can be aware of this. However, I am at a total loss how to configure the timer in this way. Do I configure the timer for 'Input capture' mode using my IRQ as the pin? Or do I configure it for 'external clock' taking the clock source as my IRQ line?

Or can I somehow speed up my IRQ response? I need it to be <100ns. I'm running at 168MHz with the peripheral clocks set at max speeds. Using HAL/CubeMX.

Cheers,

Martijn

14 REPLIES 14
Posted on March 12, 2018 at 02:50

Definitely attempting to reduce latency, but the problem I had with polling was that my IRQ pulse was too short and I sometimes missed it when reading the pin directly in a polling loop. The idea with using a timer was that it responded to the edge I wanted in hardware so that there'd be no issue missing it in the polling loop - basically it's just an edge detector. So I've set up a timer, check for the count being nonzero, then reset it to zero and do the required function. Added benefit being that a count of >1 indicates an IRQ has been missed and it should abort (nice but not required).

To be concrete, I have IRQs coming in at 2.5MHz (400ns) for which I need to kick off a pulse sequence taking about 300ns. The pulse sequence part seems to satisfy timing correctly but I need to respond to the IRQ in <100ns. The observed delay using EXTI with standard IRQ handlers is too slow, hence looking at ways to respond faster. The timer solution appears to just fit within these requirements.

I've not used naked ISRs before, but will read into it as IRQ response time often gets argued at my company when discussing merits of UC. Do you have any references? A hardware solution seems straightforward and maybe we can bodge something in, but a software solution would let us work with existing hardware.

Posted on March 12, 2018 at 03:09

Thanks for your input. Apparently I needed more coffee - I had both RM0090 and RM0385 open for comparison, since I was told to consider an F7 in the next revision 'because it's faster' - evidently I referenced the wrong one. Derp.

As I mentioned in another reply, using the timer set to external clock I poll for a nonzero count then reset the counter and perform the action - hence asking about that. This is a fancy edge detector and might not be the best solution, but it seems to give me much lower latency than EXTI - am open to and appreciate of alternate suggestions.

PM0214 and DDI0439B look like decent reads but probably good for me to study up on.

Posted on March 12, 2018 at 03:16

If you focus on latency, you have explicitly assumed that the pulse is sufficiently wide. Unless st can show otherwise, those devices have synchronous timers. Or they will miss pulses shower than their clock width.

Basically, pick your poison.

Posted on March 12, 2018 at 03:28

Oh, definitely. As stated earlier, the pulse width is ~20ns and my sysclock is 168MHz, so that's ~3 clock cycles. I've never seen it have problems detecting the edge via TIM or EXTI, but when reading the pin in a loop it misses ~1 in 10 times.

David SIORPAES
ST Employee
Posted on March 12, 2018 at 11:55

I was able to trim few cycles of ISR latency using Sleep On Exit feature which makes stacking operation shorter. See this very nice article from ARM:

https://community.arm.com/processors/b/blog/posts/beginner-guide-on-interrupt-latency-and-interrupt-latency-of-the-arm-cortex-m-processors

.

Also, as

pavel_a

‌ suggested above, you might be suffering from flash access extra wait states. You may want to try to place your ISR in RAM instead of flash even if in this case you would loose the benefit of parallelizing stacking and vector fetch operations. See which effect is dominant in you case.

Finally, double check that no FPU registers are stacked/unstacked as this would compromiseISR latency.