Interrupt latency questions
Interrupt latency questions
Hello,
I'm new to STM32's. I'm using an L432KC to develop for convenience to learn timers and interrupt handling. I'm trying to read an encoder that uses an SSI protocol. I filter the values and send it on via SSI. SSI protocol is a simple clocked serial stream.
I have a couple questions:
1) I setup a timer to try to measure external interrupt latency. I measured over 600 clock ticks! Is that right? That's an eternity.
2) How do I disable all interrupts except the ones I want. Would turning off "mills()" and Serial interrupts speed the interrupt response time.
3) I found a post on another site where someone tried to write their own ISR. Is it possible to write my own "void EXTI4_IRQHandler(void)"
Is that advisable?
4) Does STM32 have a simple hardware shift register that can be clocked directly by an external clock? That would simplify things.
5) I saw a feature "Clear-on-Capture" mentioned in a slide on an ST timer tutorial. How do I enable that feature.
These questions are a bit muddled. The main thing for me is to know if the interrupt latency is really that long and if so, can it be shortened?
I'm new to STM32's. I'm using an L432KC to develop for convenience to learn timers and interrupt handling. I'm trying to read an encoder that uses an SSI protocol. I filter the values and send it on via SSI. SSI protocol is a simple clocked serial stream.
I have a couple questions:
1) I setup a timer to try to measure external interrupt latency. I measured over 600 clock ticks! Is that right? That's an eternity.
2) How do I disable all interrupts except the ones I want. Would turning off "mills()" and Serial interrupts speed the interrupt response time.
3) I found a post on another site where someone tried to write their own ISR. Is it possible to write my own "void EXTI4_IRQHandler(void)"
Is that advisable?
4) Does STM32 have a simple hardware shift register that can be clocked directly by an external clock? That would simplify things.
5) I saw a feature "Clear-on-Capture" mentioned in a slide on an ST timer tutorial. How do I enable that feature.
These questions are a bit muddled. The main thing for me is to know if the interrupt latency is really that long and if so, can it be shortened?
-
- Posts: 142
- Joined: Mon May 06, 2024 1:46 pm
- Location: Germany
Re: Interrupt latency questions
I definitly no expert in interrupts on a STM32 ...mleo wrote: Sun Jun 02, 2024 12:55 pm 1) I setup a timer to try to measure external interrupt latency. I measured over 600 clock ticks! Is that right? That's an eternity.
Are you sure, you can measure interrupt latency with a timer?
I would use an oscilloscope in single shot mode triggered by the signal that causes the interrupt and switch inside ISR an output from HIGH to LOW and connect this output to a second channel of oscilloscope.
Here is an article about interrupt latency: https://community.arm.com/arm-community ... processors
NXP also uses arm-architecture : https://www.nxp.com/docs/en/application ... N12078.pdf
Re: Interrupt latency questions
Thanks for replying. I suspect something is wrong with the way I'm measuring the cycles. The docs say it should respond in 12 cycles, so 600 is way out of line. I suspect there's overhead added to resolve pins and stash all the states, but it can't be that many ticks. I've been reading about timer and dma access. This looks promising. It can take an external clock and drive the output of a dma buffer.
Re: Interrupt latency questions
I've made an attempt to make an usb oscilloscope using stm32f103c8 ADC
https://github.com/ag88/GirinoSTM32F103duino
this is based on the 'old' libmaple (roger's) core
https://github.com/rogerclarkmelbourne/Arduino_STM32
if ADC sampling is driven by a timer interrupt, it can at best achieve about 500khz (practically 2 us) 500 k samples per sec.
The good thing about timer interrupt driven sampling is that I can vary the sampling rates between 0-500khz practically.
But that interrupts do have latency, and it is worse if you put codes in the IRQ handler/callback.
keep codes in the interrupt handler lean as is possible. in my ADC sampling handler, I simply set a register
https://github.com/ag88/GirinoSTM32F103 ... r.cpp#L131
https://github.com/ag88/GirinoSTM32F103duino
this is based on the 'old' libmaple (roger's) core
https://github.com/rogerclarkmelbourne/Arduino_STM32
if ADC sampling is driven by a timer interrupt, it can at best achieve about 500khz (practically 2 us) 500 k samples per sec.
The good thing about timer interrupt driven sampling is that I can vary the sampling rates between 0-500khz practically.
But that interrupts do have latency, and it is worse if you put codes in the IRQ handler/callback.
keep codes in the interrupt handler lean as is possible. in my ADC sampling handler, I simply set a register
https://github.com/ag88/GirinoSTM32F103 ... r.cpp#L131
Code: Select all
void CAdcMgr::adctimerhandle(void) {
//start conversion when called
ADC1->regs->CR2 |= ADC_CR2_SWSTART;
}
-
- Posts: 142
- Joined: Mon May 06, 2024 1:46 pm
- Location: Germany
Re: Interrupt latency questions
Again I like to suggest to measure latency by a way, that is independent from software on STM32L432KC.
Can you please show your program?
Can you please show your program?
-
- Posts: 34
- Joined: Wed Jul 12, 2023 11:09 am
Re: Interrupt latency questions
Hi,
(if I remember) latency is about 1.6us in my case , ie. 100 cycles @160 MHz
so 600 cycles is not normal
maybe you can disable some system interrupts of STM32duino , but also you can set a higher preemptive priority for your critical interrupts (so you don't need to worry about the quantity of code you put into your ISRs)
you can use timer to mesure interrupt latency , for exemple , you trigger a capture the same way your interrupt is triggered , and in the ISR , you read the current value of the counter , and then you do a subtraction
please buy a ($10 clone) logical analyser , this will help you a lot for to program hardware
what do you want to "Clear-on-Capture" ?
(if I remember) latency is about 1.6us in my case , ie. 100 cycles @160 MHz
so 600 cycles is not normal
maybe you can disable some system interrupts of STM32duino , but also you can set a higher preemptive priority for your critical interrupts (so you don't need to worry about the quantity of code you put into your ISRs)
you can use timer to mesure interrupt latency , for exemple , you trigger a capture the same way your interrupt is triggered , and in the ISR , you read the current value of the counter , and then you do a subtraction
please buy a ($10 clone) logical analyser , this will help you a lot for to program hardware
what do you want to "Clear-on-Capture" ?
Re: Interrupt latency questions
I've tested ISR delay with oscilloscope and on F411 it's about 1us so ~100 cycles.
Re: Interrupt latency questions
In my experience with interrupt latency, especially with timers, it goes from 0.7µ to 3.5µS to enter and around same time for return latency (exit interrupt). It depends on complexity of interrupt code, every function that have some parameters in that code will add to latency. F4 is little faster than F1 series, but what most speed up things is to compile with -O3, and use inline for interrupt code.
As others mentioned, best way to measure it is with logic analyzer.
As for "simple hardware shift register that can be clocked directly by an external clock", SPI peripheral in slave mode is capable of doing just that.
As others mentioned, best way to measure it is with logic analyzer.
As for "simple hardware shift register that can be clocked directly by an external clock", SPI peripheral in slave mode is capable of doing just that.
Re: Interrupt latency questions
Here's the code I used:
#include <Arduino.h>
HardwareTimer *MyTim;
volatile uint32_t afterMicros;
void Clear() //Interrupt callback
{
MyTim->pause();
}
void setup()
{
Serial.begin(115200); // opens serial port, sets data rate to 115200 bps
while (!Serial) {
digitalWrite(LED_BUILTIN, HIGH);
delay(50); // wait for serial port to connect. Needed for native USB
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
if( digitalPinToInterrupt( LED_BUILTIN ) > 0 ){
attachInterrupt(LED_BUILTIN, Clear, FALLING);
Serial.println("Interrupt set");
Serial.flush();
}
// initialize LED digital pin as an output.
pinMode(LED_BUILTIN, OUTPUT);
MyTim = new HardwareTimer(TIM15);
Serial.println(MyTim->getCount(TICK_FORMAT));
Serial.flush();
delay(1000);
}
void loop()
{
// turn the LED on (HIGH is the voltage level)
digitalWrite(LED_BUILTIN, HIGH);
bool val = digitalRead( LED_BUILTIN);
Serial.print("Start: val=");
Serial.println(val?"HIGH":"LOW");
Serial.flush();
// wait for a second
// turn the LED off by making the voltage LOW
MyTim->pause();
MyTim->setCount(0,TICK_FORMAT);
MyTim->resume();
digitalWrite(LED_BUILTIN, LOW);
val = digitalRead( LED_BUILTIN);
Serial.print("After: val=");
Serial.println(val?"HIGH":"LOW");
Serial.print("TIMER --- time=");
Serial.println(MyTim->getCount());
Serial.flush();
delay(1000);
}
Re: Interrupt latency questions
I think the 'survey' above is pretty accurate, and you can use the above as an 'average'. stm32f4 being marginally faster, actually quite a bit percentage wise. But that trying to do interrupts to achieve < 1 us, I think may be just 'wishful thinking'. And on stm32f1xx, I think it won't match the 1 us speeds of stm32f4.
Interrupts are (very) useful, but that they have limits to reach any sort of 'high speed' scenarios.
in terms of how I 'measure' latency, in my 'oscilloscope' tests, as I'm using a timer to trigger ADC sampling. Hence, I try to measure 1khz or higher frequency square waves which I used another timer to generate. I can keep increasing the test signals frequency, running on another timer.
I keep increasing the ADC sampling rate from my timer code. The limit is where it is unable to measure accurately the period of the test signals generated from another timer.
that's where I got 500 k samples per sec (2 us) as 'measured' on a stm32f103, not really accurate or precise, but 'about there'
Interrupts are (very) useful, but that they have limits to reach any sort of 'high speed' scenarios.
in terms of how I 'measure' latency, in my 'oscilloscope' tests, as I'm using a timer to trigger ADC sampling. Hence, I try to measure 1khz or higher frequency square waves which I used another timer to generate. I can keep increasing the test signals frequency, running on another timer.
I keep increasing the ADC sampling rate from my timer code. The limit is where it is unable to measure accurately the period of the test signals generated from another timer.
that's where I got 500 k samples per sec (2 us) as 'measured' on a stm32f103, not really accurate or precise, but 'about there'