WinAVR und INT Priorität?

18/09/2012 - 11:15 von Stefan | Report spam
Hallo,

bisher habe ich beim ATmega unterbrechbare INT-Routinen vermieden.

Ich denke momentan aber über ein Projekt nach, wo sich das wohl nicht
vermeiden lassen wird. Dazu hab ich mir mal den Artikel

http://www.mikrocontroller.net/arti...ptroutinen

durchgelesen.

Im Prinzip ist das schon alles klar. In Assembler auf nem 8031 hab ich
früher solche Sachen auch schon gemacht.

Mir ist da jetzt nur eine Aussage in dem Artikel aufgefallen, die mir
nicht ganz einleuchtet:

snip -
#include <avr/interrupt.h>

ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */
{
/* Interrupt-Code */
}

Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass
hier beim Aufrufen der Funktion das Global Enable Interrupt Bit durch
Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle
Interrupts zugelassen werden – auch XXX-Interrupts.

Bei unsachgemàsser Handhabung kann dies zu erheblichen Problemen durch
Rekursion...

Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle
deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster
als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau:
...

ISR (XXX)
{
// Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen

<<Dektiviere die XXX-IRQ>>

// Erlaube alle Interrupts (ausser XXX)
sei();

//... Code ...

// IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos
// aktivieren zu koennen
cli();

<<Aktiviere die XXX-IRQ>>
}
Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu
einer Art Endlosschleife führen würde.

- snip --

Wieso sollte sich der xxx-IRQ selbst unterbrechen können?

Ich dachte, das könnte nur ein höher priorisierter IRQ? Es müsste doch
ausreichen, das IRQ-Flag am Ende der ISR-Routine zu löschen. Dann gehen
zwar diese zusàtzlichen IRQ-Anforderungen verloren, aber bei meiner
aktuellen Anwendung wàre das sogar erwünscht.

Gruß

Stefan
 

Lesen sie die antworten

#1 Johannes Bauer
18/09/2012 - 11:27 | Warnen spam
On 18.09.2012 11:15, Stefan wrote:

Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu
einer Art Endlosschleife führen würde.



Das ist Unsinn. Eine ISR, die sich selbst unterbricht (also zweimal
aufgerufen wird), führt nicht zu einer " Art Endlosschleife".
Insbesondere ist der Gedanke der "Rekursion" hier falsch. Ein ISR ruft
nicht einen anderen ISR auf, die Stacks werden nur aufeinander
geschachtelt. Es kann halt zu Stack-Overflow kommen, wenn ISRs zu oft
aufgerufen werden. Prinzipiell bedeuted ein ISR, der zweimal zuschlàgt
noch überhaupt nicht, dass der ISR auch ein drittes Mal kommt.

Wieso sollte sich der xxx-IRQ selbst unterbrechen können?

Ich dachte, das könnte nur ein höher priorisierter IRQ? Es müsste doch
ausreichen, das IRQ-Flag am Ende der ISR-Routine zu löschen. Dann gehen
zwar diese zusàtzlichen IRQ-Anforderungen verloren, aber bei meiner
aktuellen Anwendung wàre das sogar erwünscht.



Nein, das hast du falsch verstanden. Bei der 8-Bit AVR Architektur
entscheidet die Prioritàt (also die Position in der Vektortabelle) nur
darüber, welcher aufgerufen wird, wenn gleichzeitig zwei Interrupts
anstehen (also die IFs gesetzt sind). Die 8 bit AVR-Architektur kennt
aber nur zwei Priolevels, IRQ und !IRQ. Insofern nützt da die
Priorisierung recht wenig.

Wenn du in einer ISR IRQs wieder zulàsst, kann jeder (auch der, der
gerade abgearbeitet wird), wieder zuschlagen.

Viele Grüße,
Johannes

Ähnliche fragen