mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt-Priorität


Autor: Hans Imglück (obiwahn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
Ich bin mir nicht sicher,ob ich das englische Datenblatt (AT90S2313) 
richtig interpretiert habe. Es geht mir um Interrupt-Programmierung.
Ich benutze in meinem Programm die Ext.Interrupts 0+1 und den 
Timer0-Überlauf-IRQ. Wenn ich das Datenblatt richtig verstanden habe, 
könnte zB. je nach Priorität ein IRQ uU. eine andere laufende 
IRQ-Routine unterbrechen. Das ist aber nicht erwünscht ! Kann ich das 
irgendwie verhindern ?

Autor: Ch D. (chrisu) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
du kannst einfach während des Interrupts Interrupts Global "verbieten".

am anfang des Ints: __asm("cli");//Interupts verbieten
am ende des Ints :  __asm("sei");//Interupts wieder erlauben.

mfg chrisu

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst es Dir auch schenken. Die einfachen AVRs haben keine 
Priorisierung der Interrupts. Wird ein Interrupt abgearbeitet, sind bis 
zum reti alle anderen gesperrt.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, und es wird nach jedem reti erst ein Befehl im Hauptprogramm 
abgearbeitet, bevor wieder ein Interrupt aufgerufen werden kann.

Autor: Hans Imglück (obiwahn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm. Wenn Swen recht hat, wäre das also kein Problem.
Wenn ich aber mal einen AVR hätte, der die Interrupts nach Priorität 
abarbeitet und ich Chrisus lösung nehme, sehe ich ein anderes Problem.

Es könnte dann ja passieren , das ein zweiter , anstehender IRQ 
ausgelöst wird, genau zwischen dem SEI und dem RETI der laufenden 
IRQ-Routine 1.
Der Programmablauf würde dann ja folgendermaßen aussehen :


cli     ;IRQ-Routine 1
div. Befehle
sei     ;IRQ-Routine 1
        ;Auslösen der IRQ-Routine 2
cli
div. Befehle
sei     ;IRQ-Routine 2
reti    ;IRQ-Routine 2

ein befehl des Hauptprogramms

reti    ;IRQ-Routine 1

weiter im Hauptprogramm

Oder mach ich da einen Denkfehler ?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans Imglück schrieb:
> Oder mach ich da einen Denkfehler ?

Nein, weshalb das von Ch D. Vorgeschlagene nicht nur unnötig, sondern 
sogar potenziell gefährlich ist.

Bei allen AVRs sind Interrupts allgemein automatisch gesperrt, so lange 
eine ISR abgearbeitet wird.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Es könnte dann ja passieren , das ein zweiter , anstehender IRQ
>ausgelöst wird, genau zwischen dem SEI und dem RETI der laufenden
>IRQ-Routine 1.
>Der Programmablauf würde dann ja folgendermaßen aussehen :...

Abgesehen davon, das das bei AVRs nicht geht (bei anderen schon), wäre 
es bei ordentlich programmierten Interruptroutinen kein Problem.

MfG Spess

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:

> Abgesehen davon, das das bei AVRs nicht geht (bei anderen schon)

Natürlich geht das. Das sei im Vorschlag von chriso öffnet die 
Möglichkeit für verschachtelte Interrupts.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Natürlich geht das. Das sei im Vorschlag von chriso öffnet die
>Möglichkeit für verschachtelte Interrupts.

Nein. Er versucht das unnötigerweise zu verhindern.

>am anfang des Ints: __asm("cli");//Interupts verbieten
>am ende des Ints :  __asm("sei");//Interupts wieder erlauben.

MfG Spess

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Natürlich geht das. Das sei im Vorschlag von chriso öffnet die
>>Möglichkeit für verschachtelte Interrupts.
>
> Nein. Er versucht das unnötigerweise zu verhindern.

Du hast den Zusammenhang offenbar überhaupt nicht mitbekommen.

Ch D.:
Unsinniger Vorschlag mit den cli/sei in der ISR.

Hans Imglück:
Wenn man das benutzt, kann dann nicht das passieren:
(Beschreibung von verschachtelten Interrupts wegen dem sei am Ende der 
ISR)

Dein Kommentar zu dieser Befürchtung:
geht bei AVRs gar nicht

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans Imglück schrieb:
> Hm. Wenn Swen recht hat, wäre das also kein Problem.
> Wenn ich aber mal einen AVR hätte, der die Interrupts nach Priorität
> abarbeitet und ich Chrisus lösung nehme, sehe ich ein anderes Problem.
...
>ein befehl des Hauptprogramms

Das ist natürlich so nicht richtig. Abgearbeitet wird ein Befehl des 
durch den Interrupt unterbrochenen Programmteil. Das kann natürlich auch 
eine andere (oder so gar die gleiche) Interruptroutine sein.

Oliver

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sicher, dass ein SEI in der ISR greift und das nicht anderweitig 
geblockt wird?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven schrieb:
> Sicher, dass ein SEI in der ISR greift und das nicht anderweitig
> geblockt wird?

Ja. Man kann definitiv mit einem SEI die Interrupts innerhalb einer ISR 
freigeben.

Autor: Thomas Frosch (tfreal10)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Sven schrieb:
>> Sicher, dass ein SEI in der ISR greift und das nicht anderweitig
>> geblockt wird?
>
> Ja. Man kann definitiv mit einem SEI die Interrupts innerhalb einer ISR
> freigeben.

Wenn das so ist muss ich dann am Ende des interrupts wieder cli machen? 
oder würde ich mit einem cli am Ende die Interrupts komplett abschalten?

Also ich möchte z.B. bei einem Interrupt an einem Pin andere Interrupts 
zulassen bei einem Timer Interrupt aber nicht. So dass praktisch das 
Timer Interrupt eine höhere Priorität hat.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Frosch schrieb:

> Wenn das so ist muss ich dann am Ende des interrupts wieder cli machen?

Nein.

> oder würde ich mit einem cli am Ende die Interrupts komplett abschalten?

Nein. Ein cli am Ende der ISR hat praktisch keinen Effekt. Die 
Interrupts wären nur für eine kurze Zeit gesperrt, denn das reti danach 
gibt sie gleich wieder frei.

> Also ich möchte z.B. bei einem Interrupt an einem Pin andere Interrupts
> zulassen bei einem Timer Interrupt aber nicht. So dass praktisch das
> Timer Interrupt eine höhere Priorität hat.

Gerade bei Interrupts an einem Pin ist ein sei() in der ISR allerdings 
eine riskante Sache. Wenn das Signal an dem Pin nämlich prellt (z.B. 
Taster), oder einfach nur häufiger kommt als erwartet, hast du ruck-zuck 
sich selbst unterbrechende Interrupts.

Autor: Andy H. (vinculum) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
genau, und der stack läuft über und dann ist schicht
deshalb finger weg von sei in einer isr!!!

Autor: Gad Zinkler (gad)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Thema Interrupts und Priorität scheint ja ein nie mehr endendes 
Problem zu sein.

Habe schon so viel im Internet gelesen darüber und leider auch viel 
Unsinn.
Habe gerade selber das "Problem", dass ich eine Priorität brauche, weil 
ich einige kurze aber häufig auftretende Interrupts habe und dann wieder 
lange aber seltener auftretende.

Hatte auch überlegt, die langen Interrupts durch ein Flag zu ersetzen 
und dann im Main die eigentliche Arbeit zu machen.
Das geht aber nur, solange die Main klein genug ist um das in der 
nötigen Zeit zu schaffen. Schließlich kommt ja in die Main alles 
"unwichtige" rein, was halt irgendwann mal bearbeitet werden soll. Das 
kann dann schon recht viel werden.

Daher habe ich mich entschlossen, einen Interrupt-Handler zu schreiben, 
der Prioritäten verwaltet.
Dazu springe ich in der Vectortabelle nicht direkt auf das 
Unterprogramm, sondern auf das Label für die Priorität. Dort wird dann 
ein Prioritätenregister gesetzt.
Anschließend wird der Interrupthandler aufgerufen und arbeitet nach 
Priorität alle Interrupts ab, bei denen das Flag sitzt.
Natürlich werden alle vom Interrupt-Handler benutzen Register im Stack 
gesichert.

Das ganze funktioniert tadellos. Selbst wenn ich einen bereits laufenden 
Interrupt erneut auslöse, wird dieser erst beendet und anschließend 
gleich nochmal bearbeitet.

Einziger Nachteil ist, man braucht etwas extra Rechenzeit für den 
Interrupt-Handler.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ch D. schrieb:
> am anfang des Ints: __asm("cli");//Interupts verbieten
> am ende des Ints :  __asm("sei");//Interupts wieder erlauben.

NEIN, NEIN, NEIN!!!

Erstens ist es überflüssig, das der AVR die Interrupts von ganz alleine 
sperrt, wenn ein IRQ ausgelöst wird.

Zweitens erzeugst du gerade genau durch das sei am ende der ISR genau 
das, was du eigentlich verhindern wolltest!  Normalerweise werden die 
Interrupts erst wieder beim Rücksprung (also beim reti) wieder 
freigegeben. Wenn du nun sein sei ans Ende der ISR schreibst, werden sie 
vorher wieder freigegeben und anstehende interrupt werden bearbeitet, 
bevor der aktuelle verlassen und damit z. B. der Stack aufgeräumt wurde.

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.