fastest possible interrupts?

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone know, or have a reasonable idea, what is the highest speed input signal that an xmega32E5 could respond to as an interrupt?  I'm running my xmega 32E5 at 30 MHz clock speed but getting strange results if I attempt to process interrupts on a pin (falling edge) with input of about 1 MHz.  That may be asking too much of the CPU.  I did not see any tech data in the xmega 32E5 datasheet about speed limits on interrupts, though there is data that says how many clock cycles it takes to respond to interrupts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

First how did you make the program ? C ASM 

 

A AVR take the same time as a call+ret (normally 7 clk), add the time to move to the code 2-3 clk Then there will be some jitter depending of which instruction(and where in it) it was when the ISR came.

 

That is the HW, then there is the extra code to save SFR registers etc. 

For a simple program in C 30 clk (for you 1 MHz) is about the limit for a simple ISR, but it will take most of the CPU time. (In ASM down to about 15 clk).

 

What are you trying to do? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The number of interrupts any uC can process depends on it's clock speed and the number of instructions to execute for such an interrupt.

When programming in about any language there is some additional overhead for an interrupt. The interupt vector has to be loaded / jumped to, registers have to be pushed before and popped after the interrupt function code itself.

For analysing the overhead, a look at the .LSS / listing output of the (presumably GCC) compiler is very effective, or you can run it in a simulator /emulator / ICE.

 

During some test some time ago (normal AVR) I had my interrupt routine consuming about 80% of CPU time without it loosing a single one (high speed quadrature).

(Then I abandoned that project for a uC with hardware Quadature support, so I did not do really exhaustive testing).

 

For a normal AVR, the CPU executes at least a single instruction before it can be interrupted again.

This will probaby not have much impact on your interrupt count, but can be used for stepping through the code / debugging.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

For a normal AVR, the CPU executes at least a single instruction before it can be interrupted again.

If you want to avoid that then replace place a SEI before RETI. 

It will always cost 1 clk, but you will never "wait" for a slow instruction. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The number of interrupts any uC can process depends on it's clock speed and the number of instructions to execute for such an interrupt.

 Plus time for whatever the exception processing does "in hardware."  AVRs don't do much more than the vector load and "call equivalent", but ARM Cortex pushes at least 7 and as many as 34 registers on the stack (in addition to the return address) before the ISR even gets a chance to start...  (as a result, the ISR can be "sparser" than an AVR ISR - much of what would need to be saved is already saved.)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
If you want to avoid that then replace place a SEI before RETI. It will always cost 1 clk, but you will never "wait" for a slow instruction.
This is a very bad idea when trying to get as many interrupts out of your uC as possible. Instead of missing some interrupts during a too high load, you risk a stack overflow if the registers pushed during interrupt entry do not get popped of the stack.

 

Edit:

As joeymorin (below) pointed out I made a mistake here. I'm a C / C++ programmer and I misplaced the last C statement of an interrupt (after which the popping starts) to asm where you can put SEI and RETI next to each other.

But though harmless, it's still useless. Adding an extra instruction to your ISR (= always executed) to prevent 1 single instruction to be executed after the ISR before it can be triggered again is not a speed gain in the number of ISR's / s.

 

With 1M interrupts / s  a few kB of stack space can be filled very fast. And the gain ( 1cpu cycle / interrupt) is very small, I'd be surprized if it's > 5%.

 

Addition to my #3:

So your Xmega is running @ 30MHz and you can get near a 1MHz interrupt rate. This leaves you with just 30 cpu cycles to process an interrupt.

That is not much, and you've probably reached the limit of what you can squeeze out of such hardware.

 

I believe the Xmega's have DMA, maybe you can use that to lower the interrupt rate.

 

In this thread:

https://www.avrfreaks.net/comment/2421756#comment-2421756

I explained one of the debugging techniques I use as a combination of software and a cheap Logic Analyser.

Part of it is continuously toggling  a pin while the CPU is idle. Whenever the CPU is "busy" the pin stops toggling.

Also outputting some data on pins dedicated to debugging can give a lot of usefull timing related information of what is really going on under that little black hood of your uC.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

Last Edited: Mon. Mar 19, 2018 - 11:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a very bad idea when trying to get as many interrupts out of your uC as possible. Instead of missing some interrupts during a too high load, you risk a stack overflow if the registers pushed during interrupt entry do not get popped of the stack.

Incorrect.

 

The AVR guarantees that at least one instruction will be executed after an sei (actually, after the I bit is set by any means).  As such, the RETI immediately following the SEI is guaranteed to run, and the stack is therefore at no risk of overflow.

 

The real risk is that the code which was interrupted can get starved if there are consistently pending interrupts waiting to be serviced.  Under normal circumstance, the interrupted code would get at least one instruction in between invocation of any pending interrupt's ISR.

 

I fear you mistaken @sparrow2 for a newbie ;-)  Rest assured he knows what he's doing.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are several things that affect the interrupt execution speed:

 

1) Latency. This is the number of clocks between the physical interrupt and when the service routine begins to execute. This number varies with the instruction and, for most AVRs, is in the range of 6 to 9 clocks.

 

2) Preamble (might not be the precise term). This is nominally hidden code that executes at the beginning of the ISR. It saves various registers, especially the Status Register, that would otherwise be "clobbered" during execution of the ISR. The more that the ISR does, the more that has to be saved.

 

3) ISR execution, itself.

 

4) Postamble (again, might not be the precise term). This is also hidden, and restores all of the registers and memory locations that were saved in the preamble.

 

5) Return. The few instructions that return the execution back to where it was when the ISR "hit".

 

So, not even counting the ISR execution, the overhead can easily exceed 20-30 clocks. Thus, with a 1MHz interrupt rate, it is really easy to take longer in the ISR than the 30 clocks that is the maximum available to you.

 

Lesson: 1MHz is likely too high an interrupt rate to give reliable code execution.

 

Jim

 

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jitter can be avoided and latency made deterministic by sleeping the CPU. Use idle mode and it will always take a predictable number of cycles to wake up.

 

This thread has some interesting info: https://www.avrfreaks.net/forum/...

 

With a 1MHz interrupt rate you have 30 cycles per interrupt trigger event. 5 cycles to enter the interrupt (save PC, execute JMP at interrupt vector). Datasheet for the A3U gives the wake up time from idle as 2uS at 2MHz, which is 4 cycles. Probably 1 cycle for the port to trigger. So let's say 10 to get the interrupt started, leaving you 20 cycles to do everything and execute the RETI.

 

Is 20 cycles enough? For this kind of frequency it might be better to try to use the event system and/or DMA. Timers can use events as the clock for things like counting. I did a project where I reliably counted a 10MHz square wave using a counter and 32MHz clock. In another I sampled a 2 wire 2MHz signal using events and DMA, which was then processed and decoded later by the CPU.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) Latency.

Since this is the Xmega Forum, one might as well mention that the Xmega has a priority interrupt controller.

The lowest level priority can also be put in round robin mode, which means that when it gets to execute it cycles through the various low level interrupts, processing one each time it gets to run.

 

So that can actually add two additional forms of latency, (for lack of a better term).

One is when the round robin, low level interrupt will actually run, and the second is that fact that High and Medium level interrupts can interrupt the low level interrupt.

 

Presumably, if one needed a very fast interrupt, one would try to structure the system so that that was the only interrupt running at the time.

 

Then, of course, is the question of whether or not one can re-structure the program to avoid the use of an interrupt, and its overhead, for the code that must run fast.

 

JC 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I misplaced the last C statement of an interrupt (after which the popping starts) to asm where you can put SEI and RETI next to each other.

But though harmless, it's still useless. Adding an extra instruction to your ISR (= always executed) to prevent 1 single instruction to be executed after the ISR before it can be triggered again is not a speed gain in the number of ISR's / s.

Not useless, no:

If you want to avoid that then replace place a SEI before RETI. 

It will always cost 1 clk, but you will never "wait" for a slow instruction. 

The hardware guarantees one instruction from main 'between interrupts', but that instruction could be a 1-cycle, 2-cycle, 3-cycle, 4-cycle, or (for some cores) 5-cycle instruction.  Inserting an SEI before the RETI limits that 'cost' to 1 cycle.

 

I agree it's not a general technique to increase execution speed of a single ISR (as it precludes the use of a main thread to begin with, and polling would be faster), but it can be a useful technique to limit worst-case latency for other pending interrupts.  I've used it for just such a purpose.

 

2) Preamble (might not be the precise term).

4) Postamble (again, might not be the precise term).

Prologue and epilogue.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It would really help if the OP would explain WHY he/she thinks they need an interrupt this often?   Perhaps a better way can be suggested.

 

Jim

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

joeymorin wrote:

The AVR guarantees that at least one instruction will be executed after an sei (actually, after the I bit is set by any means).  As such, the RETI immediately following the SEI is guaranteed to run, and the stack is therefore at no risk of overflow.

That is true for "classic" AVR, but not for XMega.

Executing interrupts on XMega does not clear the I flag in the first place. If they did, higher priority interrupts couldn't be serviced within a low priority one.

So using SEI in a XMega interrupt does absolutely nothing, except wasting an extra clock cycle.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fair enough.

 

Anyone heard from the OP lately? ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 3

Anyone heard from the OP lately? ;-)

He probably can't be interrupted from his current task.  A classic problem.

When in the dark remember-the future looks brighter than ever.