www.mikrocontroller.net

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


Autor: Thomas Oly (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: lemmz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Thomas Oly (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Henry (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe auch Interrupt

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: sinusgeek (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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. ;-)

~

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ist der pegelgetriggerte Interrupt aber auch nicht besser.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist denn für dich "kritisch"?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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/Entprellun...

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 %.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es dann auch sinnvoll alle ISR in eine seperate Datei zu legen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Max (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.