Feature request: TICK count upon interrupt

When the system is chugging along nicely, an interrupt can happen. Roughly 1.8 us gets spent by the firmware as it ‘saves’ what it’s doing now and gets the address of the relevant ISR and calls it. This interrupt latency of 1.8us has some jitter in it.

“It would be nice” if the ISR and the applications software could find out the TICK count at the instant the interrupt condition was detected.

My application has six sensors, all of which map to the same ISR. Once the ISR is called because one of the sensors triggered, I go into a tight loop waiting for the others to also come true. As each comes true, I grab the TICK count for later use as a sort of “time of day” clock on when things happened. My entire event set is over in roughly 10ms.

Because of the interrupt latency, I simply subtract out 1.8us from the TICK value read at the entrance to the ISR. I just wish I had better information on what the TICK was as the exact instant my first sensor came true.

With my tight loop, I can resolve things to roughly 70ns which is great for my application. Except for the 1.8us latency.

Perhaps some global could be set which is available to the applications code. Maybe it’s already there!


Or you bypass the chain of function calls imposed on you for the benefit of the ease of use of attachInterrupt().
Although it’s more involved you still can set up a “bare metal” interrupt with reduced latency.

@ScruffR, there is always an unpredictable overhead on interrupts when you consider priority and other factors. To my knowledge, there is no way to “know” when the processor will respond to the interrupt and triggers a context push and jump to ISR. As such, it is impossible to start a tick timer at that moment.

Predictability can be added by selecting a high priority for the interrupt and by going below the HAL for the ISR jump table to remove any overhead. This will achieve an “average” latency. To get “pure” counts, the events being measured need to use hardware timers or other hardware mechanism (internal or external to CPU) to achieve the accuracy needed.

1 Like

@peekay123, that’s correct, but the extra latency of well over 1µs is at least in parts owed to the call chaining incured by the HAL and Wiring layers IMHO.
So you won’t get immediate response but can cut the latency to a few hundred ns vs 1000+ns
Hence I said reduced latency and not no latency :wink:

Selecting a high priority for the “bare metal” interrupt would of course be a logical decission too.

peekay123: I do not want to start a “tick timer”. All I want is for the system to do something like,

startTick = (DWT->CYCCNT);

And then make startTick available to me. This eliminates my uncertainty and jitter.

@ScruffR, there are inherent overheads likely added due to FreeRTOS and any code that runs atomic, thus potentially blocking the interrupts. Getting to the lowest level of the jump table will absolutely reduce the overhead as you indicate.

@jim_hahn, nothing the system can do will account for the hardware switching time of the interrupt since it is done “in the works” and not visible to the code. To add the startTick code would only add more latency to the ISR since it would need to be added in the jump chain. Again, the only way to add determinism in latency is to do the actual timing with hardware.

1 Like

peekay123: Adding the startTick instruction would certainly increase the latency for everybody else. Good for me but bad for others. I suppose I could redesign my hardware to use a hardware counter inside the Photon but it’s not immediately clear (to me) how to do that. Just went to PC board anyway so a hw change is expensive and time delaying to project. Thanks!

@jim_hahn, the only way you could have done this in hardware is using timer-associated GPIO pins and likely the Input Capture mode of the times. I’m not sure you could sacrifice the GPIO to do this. You would also need to ensure all trigger events on a given timer arrived within the based clock timing defined for that time. Add to this the fact that each Input Capture would trigger its own interrupt and that makes for a fun system to align.

Your best bet is hook your ISR as low as possible on the jump stack, below the HAL. You should also use a high interrupt priority to minimize (but not guarantee) the latency. Finally, the best you can do is get a solid average ISR latency and use that as your timing offset.

1 Like