Forum: Mikrocontroller und Digitale Elektronik AVR ASM Interrupt Priorität


von Thomas Oly (Gast)


Lesenswert?

Hallo,

wollte mal kurz fragen obs eine Möglichkeit gibt verschiedenen
Interrups eine Priorität zuzuweisen?
Mir fällts nur so ein das ich am Anfang einer wichtigen Int.-Routine
einfach die Interrups ausschalte um nicht gestört zu werden, oder gibt
es eine möglichkeit Prioritäten zu verteilen. Braucht keine fertige
Lösung sein sondern eine Idee/Vorschlag genügt mir schon.

von lemmz (Gast)


Lesenswert?

hi,
der "normale" weg ist es, zu beginn einer (längeren, kritischen)
interrupt-routine das ie-register zu sichern, interrupts auszuschalten,
befehle ausführen, ie zurückschreiben, interrupts an und feddich.
prioritäten bei irq's gibts afaik nicht, würde bei RISC auch wenig
sinn machen...

von Thomas Oly (Gast)


Lesenswert?

Hallo,

ok danke für die schnelle Antwort. Heißt "sichern" auf den Stack
legen und zurückholen(push/pop) oder ist das unsicher?

von Peter D. (peda)


Lesenswert?

Ja, der AVR hat leider keine Interruptprioritäten.

Was das aber mit RISC zu tun haben soll, ist mir schleierhaft.
Egal ob RISC oder CISC, es macht in jedem Fall komplexere Anwendungen
einfacher. Sogar einige neuere PICs haben das.

Bisher habe ich es beim AVR immer geschafft, mit nur einer
Interruptpriorität auszukommen, indem ich die Interrupts so kurz wie
möglich halte, d.h. alle nicht eiligen Schritte ins Hauptprogramm
verlagere.

Interruptprioritäten in Software zu machen ist zwar theoretisch
möglich, aber sehr kompliziert. Man muß dabei höllisch aufpassen, daß
sich Interrupts nicht selber wieder aufrufen können und das auch
wirklich die richtigen Register richtig gesichert werden.

Da die Interrupt-Enable-Bits leider überall verteilt sind und obendrein
die Interrupt-Pending-Bits ausmaskiert werden müssen, ist das eine
äußerst langwierige Angelegenheit, wärend der alle Interrupts gesperrt
sind.
Mit anderen Worten, die Interrupt-Response-Zeit kann sich dadurch
drastisch verschlechtern.


Peter

von Chris (Gast)


Lesenswert?

Hallo,

immer wieder heißt es, der AVR hätte keine Interrupt-Prioritäten. Im
Manual, z.B. zum 2313, liest man jedoch:

"The complete list of vectors is shown in Table 2. The list also
determines the priority levels of the diferent interrupts. The lower
the adress, the higher the priority level. Reset has the highest
priority,...."

Widersprechen sich die beiden Aussagen nicht? Klar ist, daß man als
Anwender an diese Tabelle gebunden ist, außer man bemüht sich in der
Software, das zu ändern. Wie lassen sich denn beide Aussagen in
Einklang bringen?

Gruß

von Peter D. (peda)


Lesenswert?

Ich vermute mal, daß es sich dabei um einen Übersetzungsfehler handelt.

In anderen Architekturen wird das richtiger als Auflösungsreihenfolge
bezeichnet.
D.h. es ist damit die Reihenfolge gemeint in der entschieden wird,
welcher Interrupt angesprungen wird, wenn mehrere Interruptquellen
gleichzeitig gesetzt sind, z.B. wenn alle Interrupts über eine längere
Zeit global gesperrt waren.


Peter

von Florian Pfanner (Gast)


Lesenswert?

Genau so ist es. Denn der AVR löscht ja bei jedem Eintritt in eine ISR
das Interrupt-Enable-Bit. Nach der ISR wird es wieder gesetzt. Also
gibt es eigentlich eine Unterbrechung der ISR durch eine andere.

Ich habe das aber in einer Anwendung schon benötigt. Also hab ich in
meiner, um einiges längere, Routine das dazugehörige
Interrupt-Enable-Bit gelöscht und dann die Interrupts Global wieder
freigegeben. Am Ende der Routine hab ich das Bit dann wieder gesetzt.
So konnte diese ISR durch eine andere (in diesem Fall höhere ISR)
unterbrochen werden, aber Sie konnte sich nicht selbst aufrufen.

Gruß, Florian

von Max (Gast)


Lesenswert?

Dann grabe ich mal dieses schöne Thema wieder aus! :-)

Wie sieht es denn bei folgenden Beispiel aus!

Ich habe zum Beispiel einen Overflow Timer Interrupt und ein INT0 
Interrupt, wo ein Taster dran ist. Beim Timer Interrupt wird eine 
Variable hochgezählt. Btw. muss die volatile sein?

So jetzt halte ich den Taster gedrückt. Kommt der Timerinterrupt 
trotzdem noch zum Zuge?

von Henry (Gast)


Lesenswert?

Variable volatile? Ja wenn sie nicht nur im Timer Interrupt sondern auch 
in einem anderen Interrupt oder Hautprogramm benutzt wird.

Sobald ein Interrupt aktiv ist sind alle weiteren Interrupt 
Abforderungen gesperrt. Man muss in der Interrupt Routine ein EI machen 
damit die anderen Interrup Anforderungen den aktuellen Interrupt 
unterbrechen können.

Die Interrupt Priorität hat damit nichts zu tun. Sie regelt die 
Reihenfolge bei gleichzeitigem Auftreten von mehreren Interrupt 
Anforderungen.

von Rolf Magnus (Gast)


Lesenswert?

> Die Interrupt Priorität hat damit nichts zu tun.

Doch , eigentlich ist sie genau das. Höherpriore Interrupts können 
niederpriore unterbrechen, umgekehrt aber nicht. Das unterstützt der AVR 
nicht, sondern nur:

> Sie regelt die Reihenfolge bei gleichzeitigem Auftreten von mehreren
> Interrupt Anforderungen.

Siehe Posting in diesem Thread etwas weiter oben:
Beitrag "Re: AVR ASM Interrupt Priorität"

von Falk B. (falk)


Lesenswert?

Siehe auch Interrupt

von Gast (Gast)


Lesenswert?

>So jetzt halte ich den Taster gedrückt. Kommt der Timerinterrupt
>trotzdem noch zum Zuge?

Schreib doch ein Mini-Testprogramm im AVRStudio und lass es im Simulator 
laufen.

Ich tippe übrigens auf "nein", d. h. der Timerinterrupt wird nicht mehr 
aufgerufen, wenn der INT0-Interrupt auf "pegelgetriggert" konfiguriert 
ist und deshalb bei gedrücktem Taster ständig ansteht. Dieser 
Betriebszustand gibt aber in keinem normalen Programm einen Sinn. Man 
benötigt den pegelgetriggerten INT0 zum Aufwachen aus dem Power Down und 
zur Realisierung eines Single-Step-Modus für Debuggingzwecke, aber ich 
glaube nicht, dass er für sonst noch was gut ist (heißt: etwas, das man 
nicht auch mit einem flankengetriggerten INT0 erledigen kann).

von sinusgeek (Gast)


Lesenswert?

> (heißt: etwas, das man
> nicht auch mit einem flankengetriggerten INT0 erledigen kann).

Wobei Taster am flankengetriggerten Int0 kontraproduktiv sind, es sei 
denn, man will einen Zufallsgenerator bauen. ;-)

~

von Rolf Magnus (Gast)


Lesenswert?

Da ist der pegelgetriggerte Interrupt aber auch nicht besser.

von Max (Gast)


Lesenswert?

Ahh so... und was würde man dann für ein Interrupt verfahren nehmen, 
wenn man per Tastendruck eine Aktion machen will. Polling würde ja bei 
kritischen Anwendungen nicht die optimale Lösung sein.

Worauf ich hinaus will ist, der Timer Interrupt ist wichtig aber der 
Tastendruck Interrupt auch. Aber wie könnte man das jetzt lösen, wenn 
zum Beispiel aus mechanischen Gründen der Schalter hängt. Dann würde ja 
die kritische Timer Routine nicht mehr zum zugekommen, wenn ich das 
jetzt richtig verstanden habe!?

von Sven P. (Gast)


Lesenswert?

Was ist denn für dich "kritisch"?

von (prx) A. K. (prx)


Lesenswert?

Max wrote:

> Ahh so... und was würde man dann für ein Interrupt verfahren nehmen,
> wenn man per Tastendruck eine Aktion machen will. Polling würde ja bei
> kritischen Anwendungen nicht die optimale Lösung sein.

Ich nehme an, es ist für dich sehr wichtig, dass der Tastendruck nach 
10µs und nicht erst nach 1000µs zur entsprechenden Reaktion führt. Denn 
andernfalls ist entprelltes Polling im oft sowieso schon vorhandenen 
regelmässigen Timer-Interrupt höchst einfach und problemlos:
http://www.mikrocontroller.net/articles/Entprellung#Interrupt-Verfahren_.28nach_Peter_Dannegger.29

von Gast (Gast)


Lesenswert?

>Wobei Taster am flankengetriggerten Int0 kontraproduktiv sind, es sei
>denn, man will einen Zufallsgenerator bauen. ;-)

OK, das steht dann auf einem anderen Blatt. Ein denkbarer 
Anwendungsfall: Jemand will herausfinden, wie oft ein Taster prellt. 
Dann könnte er ihn an einen flankengetriggerten INT0 hängen und in der 
ISR nur eine Variable inkrementieren, die sofort auf einen Port 
geschrieben wird.

>Polling würde ja bei
>kritischen Anwendungen nicht die optimale Lösung sein.

Nein, umgekehrt: Über Interrupt ist nicht die optimale Lösung.

Jeder Taster prellt. Wenn er beim Niederdrücken z. B. fünf mal prellt, 
dann gibts zwei Möglichkeiten: 1. Der INT0-Handler wird auch fünfmal 
aufgerufen, weil er so reaktionsschnell ist (das ist ja gerade seine 
Besonderheit). Dies dürfte kaum jemals erwünscht sein. Also muss man 2. 
irgendwie eine künstliche Verzögerung realisieren, die verhindert, dass 
der Interrupt sofort nach dem ersten Pegelwechsel erneut stattfinden 
kann. Eine Delayschleife ist dafür tabu, weil der µC in einer 
zeitkritischen Anwendung nicht ein paar Millisekunden lang blockiert 
sein darf, also muss man es mit einem Timer machen. Toll: Dann sind zwei 
wertvolle Controllerresourcen (ext. Int. + Timer) mit der Abfrage 
eines dämlichen Tasters belegt. Manche hält das nicht davon ab, es 
tatsächlich so zu machen; der Rest erkennt die Vorteile der 
Pollingmethode: Kein externer Interrupt nötig; die Resource Timer kann 
gleichzeitig noch vielen anderen Zwecken dienen; CPU-Last 
vernachlässigbar (wen nicht: Taktfrequenz des µC raufsetzen); so viele 
Taster handelbar, wie man will. Die durch die Tastenabfrage erzeugte 
CPU-Last kann man leicht rechnerisch abschätzen und kommt unter 
realistischen Bedingungen (z. B. FOSC = 8 MHz, Abfrageintervall = 10 ms, 
20 Takte für Tastenhandler) auf Werte weit unter 1 %.

von Max (Gast)


Lesenswert?

Ah stimmt dran habe ich noch nicht gedacht. Auch wenn ich jetzt nicht 
Timer und INT0 für einen "dämlichen" Taster verschwenden würde!

Da hätte ich noch eine Offtopic Frage! ;-) Nehmen wir an zwei Leute 
arbeiten an einem Projekt. Jeder schreibt seinen Teil. Beide nutzen den 
Timer Overflow Interrupt. Gibt es in einem Programm immer nur einen ISR 
zu dem jeweiligen Interrupt?! Ich würde denke ja, aber wie organisiert 
man dann so ein etwas größeres Programm?! Legt man sowas dann vorher 
durch die Vorplanung fest?

von Falk B. (falk)


Lesenswert?

@  Max (Gast)

>arbeiten an einem Projekt. Jeder schreibt seinen Teil. Beide nutzen den
>Timer Overflow Interrupt. Gibt es in einem Programm immer nur einen ISR
>zu dem jeweiligen Interrupt?!

Ja. Dort kann man aber mehrere Funktionen aufrufen.

> Ich würde denke ja, aber wie organisiert
>man dann so ein etwas größeres Programm?! Legt man sowas dann vorher
>durch die Vorplanung fest?

Wäre sinnvoll.

MFG
Falk

von Max (Gast)


Lesenswert?

Ist es dann auch sinnvoll alle ISR in eine seperate Datei zu legen?

von Falk B. (falk)


Lesenswert?

@ Max (Gast)

>Ist es dann auch sinnvoll alle ISR in eine seperate Datei zu legen?

Kann man manchen, muss man aber nicht. Geschmackssache.

MFG
Falk

von (prx) A. K. (prx)


Lesenswert?

Modularisierung. Ein Timer-Modul bestehend aus .h und .c mit 
Initialisierung und der dazu gehörenden ISR.

Wahlweise werden darin die Timer-Handler anderer Module direkt 
aufgerufen - das ist die einfache Fassung für überschaubare Projekte. 
Oder man geht einen Schritt weiter und bietet im Timer-Modul eine 
Funktion, mit der sich beliebige Timer-Handler hinzufügen lassen - dann 
wird ein flexibel (wieder-) verwendbarer Timer Scheduler draus.

von (prx) A. K. (prx)


Lesenswert?

>>Ist es dann auch sinnvoll alle ISR in eine seperate Datei zu legen?
>
> Kann man manchen, muss man aber nicht. Geschmackssache.

Wenn damit gemeint ist, dass jede ISR in ein eigenes Quellcode-File nur 
für diese ISR soll: Das ergibt nur in besonderen Fällen Sinn, etwa wenn 
der Code anders compilert werden muss (z.B. ARM/Thumb). Denn dadurch 
steigt der Aufwand und man kann in C keine Modul-lokalen Variablen mehr 
verwenden (static).

Ansonsten gehört zusammengehöriger Code zusammen und weitgehend 
getrennter Code getrennt. Also ein Code-Modul für UART mitsamt seinen 
Interrupts und getrennt davon eines für I2C.

von Max (Gast)


Lesenswert?

Ah ich finde das Forum super! ;-) Nicht so ein Kompetenzverlust wie in 
anderen Foren! :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.