EmbeddedRelated.com
Forums
Memfault State of IoT Report

AVR interrupt response time

Started by Pygmi January 12, 2005
"Jeroen" <jayjay.1974@xs4all.nl> wrote in message
news:41e5aaf7$0$6208$e4fe514c@news.xs4all.nl...
> > "Pygmi" <bronco_castor@hotmail.com> wrote in message > news:2fhFd.500$6X6.308@read3.inet.fi... > > > > "Jeroen" <jayjay.1974@xs4all.nl> wrote in message > > news:41e58945$0$6208$e4fe514c@news.xs4all.nl... > > > > > > "Pygmi" <bronco_castor@hotmail.com> wrote in message > > > news:B2fFd.411$6X6.281@read3.inet.fi... > > ... > > > > 11 cycles total time, depending on the executing instruction; or
0.6875
> > us. > > > Then it has entered your ISR; you at least need to save the > statusregister > > > and a few registers before useful work can be done. > > > > > > How did you check the response time? With a scope? > > > > > > Assembly will be neccesary if you want to sqeeze out every last bit of > > > performance. What's the application that this is so critical? > > > > > > Jeroen > > > > > > > > > > Thanks for the response. > > > > Yes, I checked the response time with scope. From external > > signal to first executed instruction of my "own" code in interrupt > > handler. > > > > I have a need to service ISA bus logic (I/O read/writes), and I have > > been told that R/W requests should be serviced within 2.5 us > > (so not actually 2 us). I'm not quite sure about the 2.5 us requirement, > > but if it is valid, it seems to be too much for AVR with 16 MHz... > > Maybe if this could be the only interrupt in the system or having > > nested interrupts. > > > > ..or I should forget all about interrupts and do the things I need > > by polling. Not very tempting. > > ..or just faster processor (which would mean also jump from > > AVR to another architecture) > > ..or the solution is a dual ported RAM?? > > ..or some other option...there are of course options...but for > > additional HW cost of course > > > > Pygmi > > > > Latency on bigger processors is usually even worse... Interrupt latency on > for example a 80386 can take hunderds of cycles. > > It's better to have some hardware to interface the ISA bus. A small cheap > CPLD is best, all you really need is an address decoder and a few
registers.
> The ISA bus runs at 8Mhz, the AVR runs at 16Mhz; this is just 2
instructions
> for each ISA bus cycle. A jump alone is 3 cycles. So it's not possible,
the
> AVR just can't do anything useful. Only a much faster CPU could do it, but > still then the load is still very high. > > The ISA interface can be done in plain HCT logic, and will only be a few > chips. A possible solution is a GAL20V8 as adress decoder. This decoder
will
> generate two strobes. One to enable a '574 that stores the data from the > databus and another to pass data from the AVR to the ISA via an '244.
INT0/1
> on the AVR can be used to let the AVR know something has been written. An > external interrupts needs to be at least 2 AVR clock cycles before it's > recognized, but to be on the safe side, it's better to use a flipflop
that's
> set by the address decoder, and reset by the AVR. The output of the FF
goes
> the INT0/1 input. This costs only 4 chips that cost next to nothing. If > board space is at premium, a 44 pin CPLD like a MAX7000S could be used. > > Jeroen >
Thanks again... What I want to do...is to enable 16 bit I/O register read/write access using inw/outw functions. And the registers are in AVR SRAM. One way to reduce load (a little bit) would be to go to 8-bit registers. (inb/outb) I already wrote an answer to Ulf's response telling that: I made a quick test today. Empty handler and then I wrote the code using inline assembly. Prologue of 17 instruction dropped down to 4 and time from external trigger from
>2.5 us down to 1.2 us or so (at 14.75 MHz).
So I think that using assembly to write handler I might just be able to do the thing. Pygmi
"CBFalconer" <cbfalconer@yahoo.com> wrote in message
news:41E614F7.76698613@yahoo.com...
> Ulf Samuelsson wrote: > > > >> And all that assumes that the executing code has no critical > >> sections implemented by disabling interrupts. Does no ARM > >> instruction take over 3 cycles? What about a return? What about > >> other interrupts and returns from them, if any. Hairy. > > > > Don't forget that the main reason for long worst case interrupt > > latencies is probably another interrupt which does not enable the > > global interrupt flag, this allowing nexted interrupt. This > > conflict will only appear AFTER customer shipment,according to > > Murphys law. You have to add together ALL interrupts in the > > system which has higher priority to find your worst case latency. > > This is not something that can be tested. You have to do the > > calculations. > > Of course it is not impossible that the OP has something that runs > a basic loop and has only one interrupt in the system, in which > case there will be no critical sections and the latency is > controlled by the longest instruction.
Actually this is something that I have considered. One interrupt for one time critical action. Rest of the stuff will probably get most of the processor time...but in second priority.
>However the return > instruction in many systems implies interrupt disable for the > following instruction, as a measure to avoid stack overflow in some > worst cases. There are also special cases, such as the x86 string > instructions when using a repeat prefix. Don't know about the ARM. > > -- > Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net) > Available for consulting/temporary embedded and systems. > <http://cbfalconer.home.att.net> USE worldnet address! > >
Pygmi
"Mike Harrison" <mike@whitewing.co.uk> wrote in message
news:i89bu0l5c8plgi8kiueeqrlha7ohikvbj6@4ax.com...
> On Wed, 12 Jan 2005 19:40:17 GMT, "Pygmi" <bronco_castor@hotmail.com>
wrote:
> > >I just started my first time critical project with AVR's. > >And time critical meaning interrupt response times. > >So far I have been using avr-gcc (3.3.x) and I have been > >pretty happy with it. And I have written ALL code in C. > > For the lowest latency, the fastest way is to dedicate some registers for
use only within the
> interrupt code - that way you don't have to push/pop anything, just copy
status to a register.
> > If you can tell your C compiler to never use certain registers in
foreground code, and write your
> int code in assembler, this will give the fastest response. >
Wow, nice idea. If that can be done... Anyway handy idea. And if this whole thing goes to assembler, that is the way to go.
> It may be that the standard C int handler can be modified to reduce what
it saves if it doesn't use
> all the regs it saves - take a look at the assembler it generates - you
may be able to hand-tweak
> it. >
Yes, another possibility. Thanks Pygmi
> Actually I made a quick test today. Empty handler and > then I wrote the code using inline assembly. Prologue of > 17 instruction dropped down to 4 and time from external > trigger from >2.5 us down to 1.2 us or so (at 14.75 MHz). > > I was also able to snip few instruction out of my own code. > So, I think there is hope. It is possible to get all done within > 2.5 us. But not with handlers written using C/gcc combination. > Maybe with C/IAR or some other compiler. And of course > by writing those critical parts in assembly. > > I do understand also that this only half way there. I need to > design & write the other code in such away, that this one > critical handler is serviced with minimum delay... > But it is possible....maybe. > > If there just was a AVR running with 25-30 MHz clock. > > >
AT76C713 runs at 48 Mhz, should be enough! Has 24 kB internal SRAM.. AT94K05AL FPSLIC runs at 35 MHz, has 20 kB SRAM and a small FPGA. You could conceivably do something in the FPGA. Both loads their code SRAM from an external serial EEPROM -- Best Regards Ulf at atmel dot com These comments are intended to be my own opinion and they may, or may not be shared by my employer, Atmel Sweden.
> > For the lowest latency, the fastest way is to dedicate some registers
for
> use only within the > > interrupt code - that way you don't have to push/pop anything, just copy
status to a register.
> > If you can tell your C compiler to never use certain registers in
foreground code, and write your
> > int code in assembler, this will give the fastest response. > >
This is the way to do it in IAR: __no_init __register unsigned char R10 @ 10; Only R0..R15 (with their restricted functionality) can be handled this way -- Best Regards Ulf at atmel dot com These comments are intended to be my own opinion and they may, or may not be shared by my employer, Atmel Sweden.
> >Wow, nice idea. If that can be done... Anyway handy idea. >And if this whole thing goes to assembler, that is the way to go. >
Try -ffixed-rn as option for gcc (this works for arm, so maybe also for AVR). -- 42Bastian Do not email to bastian42@yahoo.com, it's a spam-only account :-) Use <same-name>@epost.de instead !
"42Bastian Schick" <bastian42@yahoo.com> wrote in message
news:41e78149.93381695@news.individual.de...
> > > >Wow, nice idea. If that can be done... Anyway handy idea. > >And if this whole thing goes to assembler, that is the way to go. > > > > Try -ffixed-rn as option for gcc (this works for arm, so maybe also > for AVR). > -- > 42Bastian > Do not email to bastian42@yahoo.com, it's a spam-only account :-) > Use <same-name>@epost.de instead !
I will, next week. Thanks. Pygmi
"Ulf Samuelsson" <ulf@NOSPAMatmel.com> wrote in message
news:34p9t7F4bac6vU4@individual.net...
> > > For the lowest latency, the fastest way is to dedicate some registers > for > > use only within the > > > interrupt code - that way you don't have to push/pop anything, just
copy
> status to a register. > > > If you can tell your C compiler to never use certain registers in > foreground code, and write your > > > int code in assembler, this will give the fastest response. > > > > > This is the way to do it in IAR: > > __no_init __register unsigned char R10 @ 10; > Only R0..R15 (with their restricted functionality) can be handled this way > > -- > Best Regards > Ulf at atmel dot com > These comments are intended to be my own opinion and they > may, or may not be shared by my employer, Atmel Sweden. > >
Have to check gcc for that. Thanks. Pygmi
"Ulf Samuelsson" <ulf@NOSPAMatmel.com> wrote in message
news:34p9t6F4bac6vU3@individual.net...
> > Actually I made a quick test today. Empty handler and > > then I wrote the code using inline assembly. Prologue of > > 17 instruction dropped down to 4 and time from external > > trigger from >2.5 us down to 1.2 us or so (at 14.75 MHz). > > > > I was also able to snip few instruction out of my own code. > > So, I think there is hope. It is possible to get all done within > > 2.5 us. But not with handlers written using C/gcc combination. > > Maybe with C/IAR or some other compiler. And of course > > by writing those critical parts in assembly. > > > > I do understand also that this only half way there. I need to > > design & write the other code in such away, that this one > > critical handler is serviced with minimum delay... > > But it is possible....maybe. > > > > If there just was a AVR running with 25-30 MHz clock. > > > > > > > > AT76C713 runs at 48 Mhz, should be enough! > Has 24 kB internal SRAM.. > AT94K05AL FPSLIC runs at 35 MHz, has 20 kB SRAM and a small FPGA. > You could conceivably do something in the FPGA. > Both loads their code SRAM from an external serial EEPROM > > -- > Best Regards > Ulf at atmel dot com > These comments are intended to be my own opinion and they > may, or may not be shared by my employer, Atmel Sweden. > >
AT76C713?? Never heard. I'll check the info. Need to check datasheet, availability and pricing and tools and... as well. But thanks anyway Pygmi
"42Bastian Schick" <bastian42@yahoo.com> wrote in message
news:41e78149.93381695@news.individual.de...
> > > >Wow, nice idea. If that can be done... Anyway handy idea. > >And if this whole thing goes to assembler, that is the way to go. > > > > Try -ffixed-rn as option for gcc (this works for arm, so maybe also > for AVR). > -- > 42Bastian > Do not email to bastian42@yahoo.com, it's a spam-only account :-) > Use <same-name>@epost.de instead !
Shortly checked the -ffixed-rn option It is "accepted" by the compiler...but not quite sure if a got what I wanted. Need to do some testing...bevause this is what I want to do. See below. Conversation about this issue is over. But just in case someone is interested how things are developing... I did think about optional solutions and now I do really have them. 1. The one Mike suggested; manipulating the assembler gcc generates 2. Writing all (at least interrupt handlers) in assembler. 3. In-line assembly...and 'naked' attribute 4. .... Well I did try options 2 and 3 using Mega8 running at 14.7456MHz. OPTION2: .global SIG_INTERRUPT0 SIG_INTERRUPT0: cbi _SFR_IO_ADDR(PORTB), PB0 sbi _SFR_IO_ADDR(PORTB), PB0 reti It takes less than 0.6 us to start my own handler code. As both cbi and sbi take 2 cycles, line PB0 got back up within 0.8 us. OPTION3: I defined new kind of signal handler type: #define NAKED_SIGNAL(signame) \ void signame (void) __attribute__ ((signal,naked)); \ void signame (void) NAKED_SIGNAL(SIG_INTERRUPT0) { cbi(PORTB,0); sbi(PORTB,0); } Exactly same kind of timing as in option 2. Which is natural as naked makes gcc to generate fully empty handler function. No prologue code, nothing...not even reti! So, with both options I was able to get <0.6 us response. Pretty much every time. I know that changes a bit depending what is being executed at the time interrupt line changes. But not too much...max 0.15-0.2 us, I think (as I decided not to write 'concurrent' handlers). I can write other code using polling. Some further testing is still needed, but IF I can write the code using registers specifically dedicated for this one job only and maybe pushing only couple of registers (2 cycle each)..... well, I still think that I can do the job within targeted 2.5 us. Thank you all for your hints...it really helped me to focus on relevant things/issues to look for. Pygmi

Memfault State of IoT Report