Timings, Latencies and all that - redux


Well-known member
Attached is (A) a sketch that measures timings for adc reads, digital read, write, toggle, shortest pulse, and interrupt latency measured as time from edge assertion to the user supplied ISR, and (B) a header file generated by the sketch that lists the measured timings. The timings are measured by the processor cycles counter and some where checked with a scope (see the image below).

The latency is the issue I would like to inquire about. The ARM documentation describes 12 cycles to get to a non vectored interrupt. But the measured time in the tests is and average of 104 cycles and a maximum of 123 cycles (173 nsecs to 205 nsecs). That is incredibly slow and the jitter is incredibly large for a real time platform.

The ARM documents describe what sounds like a very nice realtime oriented interrrupt facility, with an easy interface to c code and a rapid context save to stack, as is the case in most processors designed for realtime applications. So, it seems like we ought to be able to get to something close to spec on the latency.

The question then is:

How do we setup an ISR so that we have faster entry, ideally - close to the spec, and with minimal jitter?

Here is the promised scope image produced by the latency test. Two pins are bridged, the isr is attached to one, and triggered by writing high to the other. The isr reads the cycle counter and returns the digital level to low. We see the duration as 210 secs, similar to the reported maximum duration.



  • Controller_Benchmark_240312.ino
    15.7 KB · Views: 9
  • T4timings.h
    1.4 KB · Views: 11
P/S thinking about this a little further, the jitter is really limiting, at 25% it is just too large and easily a show stopper for what would otherwise be some great applications for a 600MHz ARM platform.

Perhaps there is another API that I am not aware of to attach an ISR. It would surely be worthwhile to make one available or at least provide an example or make a short post to describe how to do it manually.

Thank you
attachInterruptVector() simply puts the address of the ISR into the vector table. That is literally the only way interrupts work; the exception handling code saves volatile registers and calls the ISR like a regular C function. The only "variable" part is if other interrupts are happening around the same time (since the CPU is smart enough to branch to another pending interrupt from a returning one without unstacking the volatiles) and if the FPU is set to perform lazy context switching, which I believe it is by default.

(Using a pin to time this is not recommended as all the GPIOs share a common vector, which uses a handler to read all the pins to find which one(s) triggered it.)
@jmarsh, if you are interested, see Pauls' reply here https://forum.pjrc.com/index.php?threads/t4-interrupt-latency-and-etc.74688/post-340883

Paul confirms that there is a "generic" handler that calls the user supplier function, and provided quidance on how to bypass that layer, presumably with some hope of not too adversely disrupting the rest of the firmware environment.

The latter is what I was concerned about and what I was hoping for when I posted the question.
That is the GPIO handler that I mentioned. It doesn't apply to ISRs in general, e.g. ADC, timers, FlexIO...