Pages: [1]   Go Down
Author Topic: Interrupt response time  (Read 1019 times)
0 Members and 1 Guest are viewing this topic.
Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello !

I would like to ask a simple question regarding external interrupt response time.

I have enabled an external interrupt in void setup() :

Code:
attachInterrupt(0,MyInterrupt,RISING);

and I am calling a single library function there (MyFunction). The called function belongs to a class (MyLib) that reads/writes something from/to the SPI bus :

Code:
void MyInterrupt() {
MyLib.MyFunction();
}
}

I have monitored the bus via a logic analyzer and found out that the response time of the called function was about 17.5 us. I am running on Arduino Pro @ 8 Mhz (SPI bus is set @ 2 Mhz).



Afterwards, when I explicitly copy the code from the library inside the MyInterrupt ISR function, the response time drops to about 8.5 us.

My question is how this large difference is justified.

Ideally, I would like my ISR code to start executing as close as possible to the rising edge of the interrupt pin.

I would really appreciate any help smiley
« Last Edit: June 26, 2012, 09:19:46 am by vpapanik » Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What you want to do is compile your code to assembly and then take a look at what it creates.

I think you'll be surprised by the number of instructions used just to enter an ISR, what with all the storing of context state etc.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It takes at least 2uS to just enter the interrupt, then it takes quite a bit to jump to another function from the interrupt.
Logged

~Tom~

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, is there any way to speed up the interrupt response ?
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There are indeed. For a start it would be best to use this:

attachInterrupt(0,MyLib.MyFunction,RISING);

That way you are calling your function directly which should improve performace.

Beyond that its hard to say what can be done without seeing more code.

One thing that is a helpful thing to look at is the assembled version of the code.
If you select File->Preferences and check the 'compilation' box next to 'show veribose output'

This will show you where the temporary folder Arduino is using to compile in is located. It will also mention a filename with .elf after it, e.g.
C:\Users\*******\AppData\Local\Temp\build7146138534555655544.tmp\ProjectName.cpp.elf

If you load up cmd (command prompt) and navigate to: <Arduino IDE directory>\hardware\tools\avr\bin\
Then run:
avr-objdump -S C:\directory\to\ProjectName.cpp.elf > C:\your\documents\directory\ProjectName.asm

This will generate the assembler version of your code. If you post that I can give you some pointers in the right direction.
Logged

~Tom~

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey, thanks a very lot ! I will try and come back smiley
Logged

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I've made some changes. First I changed the Arduino stuff to pure C++ :

init phase :

Code:
setBit(EICRA,ISC01); // trigger INT0 on rising edge
setBit(EICRA,ISC00); // trigger INT0 on rising edge
setBit(EIMSK,INT0); // enable INT0 (on PORTD pin 2)

handler :

Code:
ISR(INT0_vect) {

code here

}

and I inlined the time-sensitive code inside the ISR, rather than a function call.

the result is that the interrupt response dropped to about 7μs.

Actually, the time-sensitive code is the acceleration read from a BMA180 sensor. My concern was to read the acceleration as fast as possible in order to reduce the output noise, as the datasheet suggests.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.gammon.com.au/interrupts

In there I look at response times. In particular, using attachInterrupt generates different code to making your own ISR(blah) function.

The reason is, attachInterrupt calls a function indirectly (table lookup) so the compiler must save and restore every possible register that might change. If you make an ISR function the compiler knows which registers to save and restore.

Your change above, and the speed saving, would be accounted for by that.

On my page above I calculated an attachInterrupt call takes at least 5.125 uS (at 16 MHz) but an ISR function only 2.625 uS (that would vary depending on what the function did).

Double those figures to allow for your 8 MHz clock, and add on a bit for what the function actually does, and those figures roughly agree with yours.

Quote
So, is there any way to speed up the interrupt response ?

Doubling the clock speed would help. smiley
Logged

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the input Nick !

I stick to the 8 MHz Arduino Pro, because it runs @3.3V which is pin-compatible with all my peripherals. However, it is safe to raise the clock to 12 MHz (according to datasheet specs), or even overclock it to 16 MHz, which I have read that it doesn't cause any problems under normal temperatures. I would surely consider it as an option.
Logged

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Depending on what you do in the ISR, you could try to make it ISR_NAKED.
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's not as simple as making it naked as that removes everything the compiler adds including the reti instruction which means you cant return from the inerrupt unless you add all the required inline assembly yourself.
Logged

~Tom~

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12773
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

...all the required inline assembly yourself.

...also including: saving and restoring SREG; saving and restoring all used registers.  Naked really does mean naked.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

My advice is: don't try to out-think the compiler. Why buy a dog, and bark yourself?

The compiler will save and restore the registers you use. Why defeat that, and then do it yourself?
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11694
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the input Nick !

I stick to the 8 MHz Arduino Pro, because it runs @3.3V which is pin-compatible with all my peripherals. However, it is safe to raise the clock to 12 MHz (according to datasheet specs), or even overclock it to 16 MHz, which I have read that it doesn't cause any problems under normal temperatures. I would surely consider it as an option.

12MHz is going to cause you headaches compiling a compatible bootloader - people do get away with 16MHz at 3.3V, but note that there is no guarantee that future batches of the chip will work reliably at that speed.  Of course future revisions of the chip might officially support higher clock speeds anyway...
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: