changing interrupt priority

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

Hi everyone,

I'm using a mega32 and want to change the interrupt priority of some of the interrupts.

for example, 2 of the interrupts i'm going to implement are timer1 compare match and external interrupt 0. From the datasheet (page 44, table 18 ) the interrupts at the top of the table (with lowest addresses) have highest priority. This means INT0 has priority over TIMER1 COMPA. However I want it to be the other way around such that TIMER1 COMPA has the higher priority.

So, how does one go about changing the interrups priority?
Can I simply (or not so simply :? ) change were the interrupt vectors point? eg: change interrupt vector 2 from pointing to INT0 to point to TIMER1 COMPA and visa-versa for vector 8?

Any & all feedback much appreciated
Andy

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

There is nothing you can do to change the interrupt priority of the AVR, as it is all done by the internal chip circuitry. You could use the ANA_COMP interrupt instead of INT0 to decrease the priority relative to TIMER1 COMPA.

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

There is no interrupt priority logic on the AVR, so no priority can be used or changed. :(

Every interrupt must be completed until the next interrupt take place. :!:

This thing, which was false named "priority" from Atmel, means only the resolving order in such rarely cases, when two or more interrupt sources fired simultaneously.

Peter

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

you COULD enable interrupts inside your low priority interrupt so that the "high priority" interrupt would be able to seize control.

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

Spamiam wrote:
you COULD enable interrupts inside your low priority interrupt so that the "high priority" interrupt would be able to seize control.

This is not really a second priority, its only lowering the execution level of the current interrupt down to main level.

Also with the danger, that now this interrupt can interrupt itself.
Especially on UART or TWI-Interrupts it would cause a stack overflow immediately on the first occurence.

To simulate a second priority in software, you need to disable all low priority interrupts on all low priority interrupts prior the SEI command and on the end restore all enable bits after a CLI and prior the RETI.

Peter

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

danni wrote:
There is no interrupt priority logic on the AVR, so no priority can be used or changed. :(

Every interrupt must be completed until the next interrupt take place. :!:

This thing, which was false named "priority" from Atmel, means only the resolving order in such rarely cases, when two or more interrupt sources fired simultaneously.

Peter


It also comes into force if two or more interrupts trigger while you you are in the middle of an interrupt-inhibited section (such as an ISR or a critical section).

This is a fairly common occurrence, I'd think, in a multiple-interrupt environment. And in such a situation, the order in which the pending interrupts are serviced will also be determined according to what Atmel calls "Priority".

Intuituvely, it makes perfect sense to me to assign this phenomenon the label "priority", with the caveat that there are actually many distinct priority levels (one for each interrupt source, in fact). And each priority level has exactly one interrupt source permanently assigned to it.

Unfortunately, it doesn't encompass the additional property Computer Science has come to associate with interrupt priority, namely the ability for higher-priority interrupts to usurp lower-priority interrupts but not vice-versa.

So, if we reject the label "priority" because of that distinction, then what better label should we use? Maybe "Precedence"?

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

I agree with Ifmorrison's point and will try too add to it. I will also cover old some old ground to clarify additional information even though I'm repeating some stuff that has already been said above.

danni wrote:
....means only the resolving order in such rarely cases, when two or more interrupt sources fired simultaneously.

This is not quite correct for most interrupts (most interrupts have interrupt flags). It is not just when they “fire simultaneously” which is a rare event. It is when two or more interrupt flags are already set at the same time and global interrupts are enabled. The flags are still set while global interrupts are disabled, so you can build up a backlog of interrupt flags all waiting to get their interrupt serviced. This means “fire simultaneously” becomes “fire over a period of time” which is not rare at all. Deciding which one to run first is a true priority decision. There are lots of examples in the data sheet of “atomic” operations that require disabling all interrupts (usually done with the global interrupt disable). Any one of these required “atomic” operations can also result in the need to prioritize multiple interrupt service flags when global interrupts are restored.

To avoid same interrupt nesting with the AVR you can mask out the individual interrupt currently being serviced by turning off its individual enable bit and then enable global interrupts. Before returning from the interrupt service routine, disable global interrupts and restore the individual interrupt enable bit (where global interrupts are enabled again like normal). This allows the current interrupt service routine to be interrupted by any other interrupt, except that “lower priority” interrupts than the current one can run if no higher priority interrupt flags are set since the built-in priority mechanism only applies to simultaneous interrupt flags that are individually enabled for servicing. You also have to make sure that disabling an individual interrupt enable does not also disable setting its interrupt flag or you may completely miss some interrupts (the individual interrupt flags are the mechanism that remember an interrupt needs service when the CPU cannot respond immediately).

If you wanted to “software” prioritize interrupts this way you would have to individually disable all lower priority interrupts and then re-enable them before returning from the interrupt. This can get very messy, especially if more than one interrupt can re-enable other “software lower priority” interrupts when it returns (which ones do you re-enable when another interrupt still being serviced has already disabled some of them?). This type of added complexity requires extra attention to program coding and design as bugs at this level can be very hard to find and fix. All in all, when lots of interrupts are in use this type of software interrupt priority will probably end up creating badly bloated interrupt routines that take up way too many CPU cycles in overhead management. It might work well enough to be useful when only a very few interrupts are being used.

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

lfmorrison wrote:
So, if we reject the label "priority" because of that distinction, then what better label should we use? Maybe "Precedence"?

E.g.: polling sequence

8051 data sheet:
"If requests of the same priority level are received simultaneously, an internal polling sequence determines which
request is serviced."

But "priority" should not be used, because it generate only a big confusion, since on all other CPUs except AVR the meanig was as described above.

Peter

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

Quote:
since on all other CPUs except AVR the meanig was as described above.

Now that's a loaded statement. I put it to you that there is not a 100% correlation between "priority" and support for "hardware interrupt nesting".

Take, for example, the Motofreescale 68HC11 -- It talks about "priority" in determining the order in which multiple simultaneous maskable interrupt sources are serviced, but there is no allowance hardware-controlled interrupt nesting; the I-bit in CCR still dominates.

Take, as another example, the 80x86 working with an 8259 PIC in the PC architecture (in the default operating mode used by common OSes). The 8259 allowed you to re-prioritize each of the IRQ's, but nested interrupts still had to be controlled by the software modifying CPU registers at run time.

Atmel is not alone in its use of "priority".

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

Danni,

We can go back allot farther in history than the microprocessors already mentioned. The TTL era “Interrupt Priority” chip was an external chip with 8 parallel interrupt inputs plus a cascade input for chaining more than 1 interrupt priority chip together. The output was a 3 bit binary code that prioritized the inputs into their binary value. This priority resolution was driven by dedicated logic circuitry and not “polled”. Polling is a method of achieving a goal and should not be confused with the goal itself. Its also silly to assume my point of view has any greater value just because I want back farther in history than you did. Besides, I was not aware that data sheet writers were the authorities on anything except maybe their own hardware. I could probably use early foreign language data sheet translations as evidence that microprocessors are really cars :).

Case 1: Its simple, deciding which of several active interrupt requests to run first is an interrupt priority resolution function. Please disprove this first before advancing opposing arguments.

Case 2: All you are doing is focusing on the specialized case of interrupting another interrupt that is already being serviced with a “higher priority” interrupt. This is a special case for processing interrupts that many microprocessors (including AVRs) do not even support directly with hardware. It is also an interrupt priority resolution function, but is not as basic or universal as resolving which competing interrupt to run first (all microprocessors with multiple interrupts have to deal with this one).

I'm sorry if you find it confusing that there is more than one single aspect (or case) to interrupt priority resolution. Actually I would find it confusing to pick apart each individual aspect of interrupt priority resolution (as you appear to want to do) and rename it. We agree that case 2 is an interrupt priority resolution issue. Why can't you see that case 1 is also an interrupt priority resolution issue?

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

I would refer to this as 'priority'. Again, if there are multiple interrupt sources active, the hardware chooses the highest priority source to use. With a 8051, you have high and low priority choices for each interrupt source - but in each group the priority is fixed so you can sort of juggle the overall priorities. The HC11 has fixed priorities like the AVR, so one way of coping with it is testing the other low priority interrupt flags in the higher priority ISR and jumping to this code - but think very carefully though!!!! Understand fully the interrupt mechanism of each source as some auto acknowlege. Remember- there is no magic.

Obviously it is best to avoid these situations by limiting the number of interrupt sources in an application. This might be easier said than done! Also, by keeping your ISRs lean and mean, you can ignore the priority issue in many cases.