Say each time a pin changes a timer is read cleared and restarted
In assembler latency is 5 cycles and a few more when it is read.
Howmany cycles will latency be in C including the timer-read ?
Modern C compilers generally can do as good or better job at generating code than you can by using assembler directly. For the specific section of code you mention, I would not expect much difference. You could always try it and take a look at the code that's actually produced.
Have you thought of using the Input Capture Register? Then you don't have to worry about interrupt latency, or those other interrupts happening, or places where interrupts are temporarily disabled.
In the given example Inputcapture is better indeed.
But sometimes interrupt timing really has to be tight.
How about using ASM for the interrupt routine?
(assuming nothing is executed between the int and the icall.)
gbaars:
In the given example Inputcapture is better indeed.
But sometimes interrupt timing really has to be tight.
How about using ASM for the interrupt routine?
(assuming nothing is executed between the int and the icall.)
Using assembler in your ISR is not in any way going to protect you from other ISRs or code that disables interrupts.
gbaars:
Howmany cycles will latency be in C including the timer-read ?
It could vary quite a bit depending on the code since depending on the code it may have to save/restore more registers.
Best thing to do would be to compile the actual code and look at the assembler generated.
— bill
First, don't go the Arduino 'attachInterrupt()' approach. Rather, implement the function for the ISR vector yourself. Next look into 'ISR_NAKED' which will cause the processor to save fewer state variables when the interrupt fires.
If implementing everything interrupt related and
make no use of C for it could anything else affect this?
gbaars:
If implementing everything interrupt related and
make no use of C for it could anything else affect this?
You are safe if you follow the rules:
https://www.nongnu.org/avr-libc/user-manual/assembler.html
In assembler latency is 5 cycles and a few more when it is read.
Is not.
7.7.1: The interrupt execution response for all the enabled AVR interrupts is four clock cycles minimum. After four clock cycles the program vector address for the actual interrupt handling routine is executed. During this four clock cycle period, the Program Counter is pushed onto the Stack. The vector is normally a jump to the interrupt routine, and this jump takes three clock cycles.
You’ll also have to save SOME context in addition to the raw ISR overhead and the actual timer reads/writes.
How many cycles will latency be in C including the timer-read ?
Well, let’s see. For the Arduino IDE 1.8.12, I assume you mean something like:
volatile uint16_t ocCount;
ISR(TIMER0_COMPA_vect) { // timer interrupt
ocCount += 1; // increment a counter
OCR0A += 10; // schedule next interrupt.
}
Which produces:
000005b2 <__vector_14>:
5b2: 1f 92 push r1 ; save r1 "known zero"
5b4: 0f 92 push r0
5b6: 0f b6 in r0, 0x3f ; get and save flags.
5b8: 0f 92 push r0
5ba: 11 24 eor r1, r1 ; make r1 zero, just in case.
5bc: 8f 93 push r24 ; save registers for math on ocCount.
5be: 9f 93 push r25
5c0: 80 91 b8 01 lds r24, 0x01B8 ; 0x8001b8 <ocCount>
5c4: 90 91 b9 01 lds r25, 0x01B9 ; 0x8001b9 <ocCount+0x1>
5c8: 01 96 adiw r24, 0x01 ; 1
5ca: 90 93 b9 01 sts 0x01B9, r25 ; 0x8001b9 <ocCount+0x1>
5ce: 80 93 b8 01 sts 0x01B8, r24 ; 0x8001b8 <ocCount>
5d2: 87 b5 in r24, 0x27 ; get timer register (re-uses R24!)
5d4: 86 5f subi r24, 0xF6 ; add 10
5d6: 87 bd out 0x27, r24 ; store.
5d8: 9f 91 pop r25 ; restore math registers
5da: 8f 91 pop r24
5dc: 0f 90 pop r0 ; restore flages
5de: 0f be out 0x3f, r0
5e0: 0f 90 pop r0 ; restore r0 used for flags
5e2: 1f 90 pop r1 ; restore known zero, which we didn't use.
5e4: 18 95 reti
So compared to a carefully written ASM function:
- it wastes three instructions dealing with R1.
- and two instuctions putting the flags on the stack, when it could have just stayed in a register.
- you could’ve incremented ocCount one-byte at a time, avoiding a register save/restore (by adding an additional ADD instruction…)
(I believe that 1 and 2 are improved in newer versions of the compiler, BTW.)