Forum: Mikrocontroller und Digitale Elektronik Unterbrechung eines Interrupts durch einen Interrupt


von Feivel (Gast)


Lesenswert?

Hallo zusammen,

ich hätte da mal eine Frage...

Angenommen ein Programm befindet sich gerade in einer ISR, was passiert, 
wenn während der Abarbeitung ein zweiter ISR mit höherer, bzw. mit 
niedrigerer Priorisierung einläuft.

Im Falle das die Priorisierung höher ist, wird dann der laufende ISR 
unterbrochen und der mit der höheren Prio zuerst abgearbeitet und danach 
wieder fortgesetzt?

Im Falle das die Priorisierung niedriger ist, ich nehme an, dass der 
aktuelle Prozess fortgeführt wird, bis dieser beendet ist, der neue 
Interrupt wird dann in einen Puffer geschrieben und danach bearbeitet.

Ist das so in etwa korrekt?

Danke und vG

: Verschoben durch Moderator
von funky (Gast)


Lesenswert?


von Hubertus (Gast)


Lesenswert?

Kommt auf den Typ des Prozessors/Controllers an.

Beim 8051 gab es Interrupts mit verschiedenen Prioritäten. Wichtigere 
Interrupts konnten weniger wichtige unterbrechen. Die Prioritäten 
konnten teilweise auch über Register definiert werden.

Beim AVR sind wimre alle Interrupts gleich priorisiert und können sich 
somit nicht unterbrechen.

von Rolf M. (rmagnus)


Lesenswert?

Feivel schrieb:
> Hallo zusammen,
>
> ich hätte da mal eine Frage...
>
> Angenommen ein Programm befindet sich gerade in einer ISR, was passiert,
> wenn während der Abarbeitung ein zweiter ISR mit höherer, bzw. mit
> niedrigerer Priorisierung einläuft.

Das kommt auf den Prozessor und/oder den Interrupt-Controller an.

von Bernd B. (microwave-designer)


Lesenswert?

Hallo Feivel,

Name des Prozessors wäre gut zu wissen!

Normal, was ist normal?, ist wenn während der Abarbeitung innerhalb 
einer ISR das Flag so gesetzt ist, dass keine Interrupts weiter 
aufgerufen werden. Erst mit dem Verlassen der ISR wird das Flag wieder 
zurück gesetzt. Dann kann es mit der nächsten ISR entsprechend der 
Rangfolge weitergehen.

Gruß

Bernd

von Feivel (Gast)


Lesenswert?

Ich sehe schon, dass ist nicht so trivial wie ich es mir vorgestellt 
habe.

Mir wurde in diesem Bezug eine ganz allgemeine Frage gestellt welche ich 
beantworten soll, es wird kein Prozessor genannt. Ich nehme an, dass 
hier von einem x beliebigen Typ ausgegangen wird welcher über eine 
Priorisierung von Interrupts verfügt.

In diesem Fall könnte man sagen:

ISRx läuft...

ISRy mit niederer Prio läuft ein -> ISRy wird in einen "Puffer" 
gespeichert und abgearbeitet nachdem ISRx fertig ist.

ISRy mit höherer Prio läuft ein -> ISRx wird unterbrochen und ISRy wird 
bearbeitet, nachdem ISRy fertig ist, fängt:
- ISRx von vorne an?
- ISRx wird ab Unterbrechung abgearbeitet?
- ISRx wird nicht weiter behandelt?

hmmm...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Feivel schrieb:
> Angenommen ein Programm befindet sich gerade in einer ISR, was passiert,
> wenn während der Abarbeitung ein zweiter ISR mit höherer, bzw. mit
> niedrigerer Priorisierung einläuft.
Abgesehen vom bisherigen "kommt drauf an": im Idealfall ist der 
Aufenthalt in der ISR so kurz, dass in der Zeit kein zweiter Interrupt 
einlaufen kann...   ;-)

Oder andersrum: wer in der ISR ein komplettes Apfelmännchen berechnet 
und deshalb nicht auf andere Interrupts reagieren kann, der hat im 
Softwarekonzept seines Programms irgendwas falsch gemacht.

Feivel schrieb:
> Im Falle das die Priorisierung niedriger ist, ich nehme an, dass der
> aktuelle Prozess fortgeführt wird, bis dieser beendet ist, der neue
> Interrupt wird dann in einen Puffer geschrieben und danach bearbeitet.
Das gilt auch für den Fall, dass die Priorität gleich ist. 
AVR-Controller haben z.B. nur 1 Interruptpriorität.

> der neue Interrupt wird dann in einen Puffer geschrieben
Er wird nicht extra in einen Puffer geschrieben, sondern der Interrupt 
setzt sein Interruptflag und das bleibt gesetzt, bis es durch die ISR 
gelöscht wird.
Wenn die Interruptroutine A also lange dauert und währendessen der 
niedriger- oder gleichpriore Interrupt B sogar zweimal oder mehrmals 
kommt, dann geht einer oder mehrere dieser Interrupts B "verloren". Weil 
ein bereits gesetztes Flag ja nicht nochmals gesetzt werden kann.

Feivel schrieb:
> In diesem Fall könnte man sagen:
>
> ISRx läuft...
>
> ISRy mit niederer Prio läuft ein -> ISRy wird in einen "Puffer"
> gespeichert und abgearbeitet nachdem ISRx fertig ist.
Ja.
>
> ISRy mit höherer Prio läuft ein -> ISRx wird unterbrochen und ISRy wird
> bearbeitet, nachdem ISRy fertig ist, fängt:
> - ISRx von vorne an?
Nein, sie wurde ja nur unterbrochen.
> - ISRx wird ab Unterbrechung abgearbeitet?
Ja.
> - ISRx wird nicht weiter behandelt?
Nein, sie wird an der unterbrochenen Stelle fortgesetzt. So wie es jeder 
Interrupt mit dem "Hauptprogramm" auch macht:
Hauptprogramm läuft...
ISRy mit läuft ein -> Hauptprogramm  wird unterbrochen und ISRy wird 
bearbeitet, nachdem ISRy fertig ist, wird das unterbrochene 
Hauptprogramm an der selben Stelle fortgesetzt.

So kennst du das ja auch mit 1 Interrupt:
Hauptprogramm: Du liegst auf dem Sofa und liest ein Buch.
Interrupt 1: Dein Magen knurrt und du schmierst dir eine Butterstulle. 
Wenn dir geschmiert ist, legst du dich wieder aufs Sofa un liest weiter.

Und dann mit 2 Interrupts:
Hauptprogramm: Du liegst auf dem Sofa und liest ein Buch.
Interrupt 1: Dein Magen knurrt und du schmierst dir eine Butterstulle. 
Kaum ist die Brotscheibe heruntergeschnitten...
Interrupt 2: ...klingelt der Postbote an der Haustür. Du gehst dorthin, 
holst den Brief ab und dann:
a) legst du dich aufs Sofa?
b) schneidest du nochmal ein Scheibe Brot ab?
c) schmierst du die Butter aufs Brot und gehst dann wieder zum Sofa?


BTW:
Da "läuft nix ein" und "der Puffer" ist ein einzelnes Bit (=Flag)

: Bearbeitet durch Moderator
von Feivel (Gast)


Lesenswert?

Super, vielen Dank für die Antwort.

Also kann ich es mir so vorstellen:
- Ein Interrupt wird bearbeitet (Interruptflag ist gesetzt)
- ISR mit gleicher oder niederer Prio tritt auf, wird in diesem Moment 
nicht bearbeitet, weil Interruptflag bereits gesetzt, erst wenn nach 
Abarbeitung des laufenden ISR wieder ein Interrupt eingeht, wird dieses 
wieder bearbeitet.
- Sollte aber während der Abarbeitung einer laufenden ISR ein Interrupt 
mit höherer Prio kommen, wird die aktuelle ISR an Stelle x unterbrochen 
und nach Beendigung des ISR mit der höherern Prio an Stelle x wieder 
fortgeführt.

Die Firma dankt (keine IT Firma :P)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Feivel schrieb:
> Also kann ich es mir so vorstellen:
> - Ein Interrupt wird bearbeitet (Interruptflag ist gesetzt)
Jede Interruptquelle (Timer, Counter, SPI, SIO, IO,...) hat ein eigenes 
Interruptflag. Aber eben nur eines. Es kann also nur 1 Interrupt pro 
Interruptquelle "gemerkt" werden.

von Feivel (Gast)


Lesenswert?

Wieder was gelernt... ich bedanke mich recht herzlich!

von Theor (Gast)


Lesenswert?

Feivel schrieb:
> [...]
> - ISR mit gleicher oder niederer Prio tritt auf, wird in diesem Moment
> nicht bearbeitet, weil Interruptflag bereits gesetzt, erst wenn nach
> Abarbeitung des laufenden ISR wieder ein Interrupt eingeht, wird dieses
> wieder bearbeitet.
> [...]

Nein. Das ist so nicht korrekt, jedenfalls nicht allgemein.

In der Regel, wird der Interrupt mit der niedrigeren Priorität zwar 
nicht sofort abgearbeitet, aber er wird auch nicht ignoriert, als wenn 
er nie stattgefunden hätte.
Sobald der Interrupt mit der höheren Priorität fertig ist, wird der 
Interrupt mit der niedrigeren Priorität bearbeitet. Das auslösende 
Ereignis kann durchaus auch während der Bearbeitung des Interrupts mit 
der höheren Priorität auftreten.

Ich vermute, Du bist zu diesem Schluss wegen der Bemerkung über den 
Puffer gekommen. Es wurde gesagt, das so ein Puffer nicht existiert. 
Aber es wurde auch gesagt, dass ein bzw. das entsprechende Flag gesetzt 
wird. Dieses Flag ist der von Dir gedacht "Puffer". Nur das das Wort 
"Puffer" dafür nicht verwendet wird.

Als Puffer werden Speicherbereiche bezeichnet in denen mehrere, und 
unter Umständen mehrwertige Anwendungs-Daten gespeichert werden. Im 
Gegensatz dazu sind die Interrupt-Flags keine Anwendungsdaten. Etwas 
abstrakter gesehen, mag man diese Flags durchaus als "Puffer" ansehen, 
aber das ist einfach unüblich.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Theor schrieb:
> Etwas abstrakter gesehen, mag man diese Flags durchaus als "Puffer"
> ansehen, aber das ist einfach unüblich.
richtig, denn so ein "Puffer" führt zum falschen Bild mit einem "Stapel 
mit Interruptanforderungen": jeder eintreffende Interrupt kommt auf 
einen Stapel und wird später abgearbeitet. Und wenn (weil z.B. der 
höchstpriore Interrupt durch einen Programmierfehler 10ms dauert) ein 
IO-Interrupt 5 mal kommt, dann wird der hinterher 5 mal abgearbeitet.

Und das ist eben nicht der Fall. Wie angemerkt, ist das kein "Puffer", 
sondern eher so ein "Flag" wie bei amerikanischen Briefkästen: wenn der 
Postbote montags kommt, dann klappt er die Fahne hoch. Wenn ich im 
Urlaub bin und er am Dienstag und am Mittwoch nochmal kommt, dann ist 
die Fahne schon oben und das wars. Wenn ich dann am Mittwoch abend 
heimkomme, dann sehe ich nur 1 einzige hochgeklappte Fahne und weiß 
nicht, wie oft der Postbote da war.

: Bearbeitet durch Moderator
von Olaf (Gast)


Lesenswert?

> Aufenthalt in der ISR so kurz, dass in der Zeit kein zweiter Interrupt
> einlaufen kann...   ;-)

Das klingt wie ein Aphorismus mit dem sich AVR-User die Welt schoen 
denken. :-)

Die mangelhaften Interruptfaehigkeiten, also keine Priorisierung und vor 
allem keine moegliche Einflussnahme auf die Priorisierung ueber vom User 
vergebbare Level war fuer mich einer der wesentlichen Gruende warum ich 
vor 15Jahren von AVRs auf M16C umgestiegen bin.

Olaf

von honk (Gast)


Lesenswert?

Lothar M. schrieb:
> Feivel schrieb:
>> Im Falle das die Priorisierung niedriger ist, ich nehme an, dass der
>> aktuelle Prozess fortgeführt wird, bis dieser beendet ist, der neue
>> Interrupt wird dann in einen Puffer geschrieben und danach bearbeitet.
> Das gilt auch für den Fall, dass die Priorität gleich ist.
> AVR-Controller haben z.B. nur 1 Interruptpriorität.


Das ist doch Bullshit. Natürlich haben AVRs Interruptprioritäten.
Einfach mal ins Datenblatt schauen, auch wenn das mühselig ist...

Z.B. ATmega328:
"The interrupts have priority in accordance with their interrupt vector 
osition. The lower the interrupt vector address, the higher the 
priority."

Wäre ja noch schöner, wenn der Controller jedes Mal würfeln müsste, wenn 
Interrupts gleichzeitig auftreten.

von Ingo L. (corrtexx)


Lesenswert?

honk schrieb:
> Wäre ja noch schöner, wenn der Controller jedes Mal würfeln müsste, wenn
> Interrupts gleichzeitig auftreten.
Es trifft aber nicht auf die Frage des TE, denn er fragt:

Feivel schrieb:
> Angenommen ein Programm befindet sich gerade in einer ISR...
Da sind wir schon in der ISR, denn Fall "was passiert wenn 
zeitgleicht..." kam nicht.

Also ist deine Antwort nicht falsch, Lothars aber auch nicht 
hinsichtlich der Fragestellung des TE.

von Falk B. (falk)


Lesenswert?

@ honk (Gast)

>> Das gilt auch für den Fall, dass die Priorität gleich ist.
>> AVR-Controller haben z.B. nur 1 Interruptpriorität.


>Das ist doch Bullshit. Natürlich haben AVRs Interruptprioritäten.
>Einfach mal ins Datenblatt schauen, auch wenn das mühselig ist...

>Z.B. ATmega328:
>"The interrupts have priority in accordance with their interrupt vector
>osition. The lower the interrupt vector address, the higher the
>priority."

AVRs haben von Haus aus aber keine unterbrechbaren ISRs. Wenn man die 
WIRKLICH braucht, muss man das per Software nachbilden.

Die C2000 (PICCOLO) von TI haben das auch nicht.

>Wäre ja noch schöner, wenn der Controller jedes Mal würfeln müsste, wenn
>Interrupts gleichzeitig auftreten.

Tut er nicht, aber die Priorität der Interrupts greift beim AVR nur, 
wenn mehrere Interrupts aktiv sind und zur Bearbeitung anstehen. 
Verkettete (unterbrechbare) Interrupts sind das nicht.

von Falk B. (falk)


Lesenswert?


von honk (Gast)


Lesenswert?

Falk B. schrieb:
> Tut er nicht, aber die Priorität der Interrupts greift beim AVR nur,
> wenn mehrere Interrupts aktiv sind und zur Bearbeitung anstehen.
> Verkettete (unterbrechbare) Interrupts sind das nicht.


Das ist schon klar. Nichtsdestotrotz hat er Prioritäten, insofern muss 
man diese falsche Aussage richtigstellen.


Olaf schrieb:
> Die mangelhaften Interruptfaehigkeiten, also keine Priorisierung und vor
> allem keine moegliche Einflussnahme auf die Priorisierung ueber vom User
> vergebbare Level war fuer mich einer der wesentlichen Gruende warum ich
> vor 15Jahren von AVRs auf M16C umgestiegen bin.


In Software lässt sich das zumindest teilweise umgehen. Daher taugt der 
AVR auch für viele Anwendungszwecke, in denen verschiedene 
Interrupttypen gebraucht werden. Und falls doch mal nicht, dann gab es 
ja noch die guten alten 8051er ;)

von honk (Gast)


Lesenswert?

Ingo L. schrieb:
> Also ist deine Antwort nicht falsch, Lothars aber auch nicht
> hinsichtlich der Fragestellung des TE.


Nichts für ungut, aber Lothar schreibt:
"AVR-Controller haben z.B. nur 1 Interruptpriorität."

Und das ist schlichtweg falsch, egal wie die Fragestellung war.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

honk schrieb:
> Das ist doch Bullshit.
Immer ein Kraftwort zur Hand.

> Natürlich haben AVRs Interruptprioritäten.
Das sind keine Interruptprioritäten in dem Sinn, wie sie hier 
diskutiert werden.
Denke einfach beim AVR als Inrterrupt-Level und schon hast du nur 1 
einzigen: wenn schon ein Interrrupt läuft, kann keine höher priorisierte 
Interruptquelle diesen Interrupt unterbrechen.

honk schrieb:
> "AVR-Controller haben z.B. nur 1 Interruptpriorität."
> Und das ist schlichtweg falsch, egal wie die Fragestellung war.
Ja, dann bitte ich hiermit in aller Form um Entschuldigung und 
korrigiere diese grundlegend falsche Behauptung dahingehend:
AVR-Controller haben z.B. nur 1 Interruptlevel.

Ich habe gestern auch mal "Schraubenzieher" gesagt. Auch das möchte ich 
hiermit zum "Schraubendreher" korrigieren.

Olaf schrieb:
> Das klingt wie ein Aphorismus mit dem sich AVR-User die Welt schoen
> denken. :-)
Diese Denkweise macht im Grunde das Leben einfach: man muss sich nicht 
mit irgendwelchen die Unterbrechung unterbrechenden Unterbrechungen 
herumschlagen... ;-)

> Die mangelhaften Interruptfaehigkeiten, also keine Priorisierung und vor
> allem keine moegliche Einflussnahme auf die Priorisierung ueber vom User
> vergebbare Level war fuer mich einer der wesentlichen Gruende warum ich
> vor 15Jahren von AVRs auf M16C umgestiegen bin.
Die STM32 ARM-Prozessoren bieten da auch viele Möglichkeiten. Und wenn 
man dann noch die DMY dazunimmt, dann wirds erst richtig lustig.

: Bearbeitet durch Moderator
von Ingo L. (corrtexx)


Lesenswert?

Falk B. schrieb:
> Die C2000 (PICCOLO) von TI haben das auch nicht.
Gibts da mal was was deine geliebten PICCOLO nicht können ;)?

von Peter D. (peda)


Lesenswert?

Feivel schrieb:
> nachdem ISRy fertig ist, fängt:
> - ISRx von vorne an?
> - ISRx wird ab Unterbrechung abgearbeitet?
> - ISRx wird nicht weiter behandelt?

Es gibt nur eins davon, das sinnvoll und logisch ist.

von Hubertus (Gast)


Lesenswert?

Lothar M. schrieb:
> ie bei amerikanischen Briefkästen: wenn der
> Postbote montags kommt, dann klappt er die Fahne hoch.

Eigentlich klappt man die Fahne hoch, damit der Briefträger sieht, dass 
er ne Sendung mitnehmen soll.

von Willi (Gast)


Lesenswert?

Auch beim AVR kann eine laufende ISR durch weitere Interupts 
unterbrochen werden.
Dazu muss nur in der ISR per SEI-Befehl das Interupt-Enable Flag wieder 
gesetzt werden. Dann kann jeder anstehende oder zukünftig auftretende 
Interrupt die ISR unterbrechen. Ja, auch niedriger priorisierte.
Die Priorisierung wirkt sich beim AVR nur auch die Reihenfolge 
gleichzeitig anstehender Interupts aus.
Natürlich sollte der Programmierer, wie eigentlich immer, wissen was er 
tut.


Mfg Willi

von honk (Gast)


Lesenswert?

Lothar M. schrieb:
> Immer ein Kraftwort zur Hand.


Naja, so ist es halt schön prägnant.


>> Natürlich haben AVRs Interruptprioritäten.
> Das sind keine Interruptprioritäten in dem Sinn, wie sie /hier/
> diskutiert werden.
> Denke einfach beim AVR als Inrterrupt-Level und schon hast du nur 1
> einzigen: wenn schon ein Interrrupt läuft, kann keine höher priorisierte
> Interruptquelle diesen Interrupt unterbrechen.


Das ist mir schon klar, nur könnte das auch ein unbedarfter lesen und 
dann versteht er es falsch. Also warum nicht gleich korrekt schreiben.


> Ich habe gestern auch mal "Schraubenzieher" gesagt. Auch das möchte ich
> hiermit zum "Schraubendreher" korrigieren.


Also ich bin dafür seinerzeit im Praktikum vom Lehrwerkstattsleiter rund 
gemacht worden ;)

von honk (Gast)


Lesenswert?

Hubertus schrieb:
> Lothar M. schrieb:
>> ie bei amerikanischen Briefkästen: wenn der
>> Postbote montags kommt, dann klappt er die Fahne hoch.
>
> Eigentlich klappt man die Fahne hoch, damit der Briefträger sieht, dass
> er ne Sendung mitnehmen soll.


So kenne ich es auch aus meiner Zeit drüben.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

honk schrieb:
>> Eigentlich klappt man die Fahne hoch, damit der Briefträger sieht, dass
>> er ne Sendung mitnehmen soll.
> So kenne ich es auch aus meiner Zeit drüben.
Blöd, das kann man natürlich nicht so einfach auf einen µC übertragen.
Da muss ich mir ein anderes Beispiel ausdenken...  ;-)

von Bernd B. (microwave-designer)


Lesenswert?

Lothar M. schrieb:
> Wenn ich dann am Mittwoch abend
> heimkomme, dann sehe ich nur 1 einzige hochgeklappte Fahne und weiß
> nicht, wie oft der Postbote da war.

Hallo Feivel und in die Runde,

mittlerweile habe ich ja auch dazu gelernt, dass man etwas kompliziert 
machen kann und auch straight forward.

Ich versuche einmal wiederzugeben, wie es bei meinem kleinen Prozessor 
abläuft:

Sobald die Peripherie den Bedarf nach abarbeiten einer Service Routine 
signalisiert, wird ein entsprechendes Flag gesetzt. Sofern das Global 
Interrupt Enable Flag gesetzt ist, pushed der Prozessor Status und Code 
auf dem Stack und springt in die ISR. Gleichzeitig wird das Global 
Interrupt Flag zurück genommen. Damit sind weitere ISR-Ausführungen 
blockiert und werden erst einmal keine weiteren ISR angesprungen. 
Natürlich könnte ich bei Eintritt in die erste ISR das Flag wieder 
setzen und die Blockade aufheben. Damit würde, sobald wieder ein 
Interrupt ausgelöst wird in die nächste ISR gesprungen werden, mit push 
von Codeadresse und Status, usw. Aber das Globale Flag fasse ich nicht 
an! Der Code in der ersten (einzigen ISR) wird abgearbeitet. Nun gibt es 
einige Interrupt Vektoren (ISR-Adressen), die sich unterschiedliche 
Interrupt-Quellen teilen. Ich muss bei diesen bei Eintritt innerhalb der 
ISR verzweigen und vor dem Exit der ISR prüfen, ob nicht vielleicht noch 
ein anderer weiterer Grund zu dieser ISR geführt hat. Das auch, falls 
zufällig während abarbeiten des Codes ein weiterer Interrupt zur selben 
Vektoradresse aufgetreten ist. ...oder auch falls der selbe Grund das 
Flag erneut gesetzt hat, während die ISR abgearbeitet wurde. (Das kommt 
z.B. bei Capture/Compare Funktionen vor, ... wenn man nicht aufpasst 
oder falsch denkt. Auch passiert das, wenn mehre I/O-Pins gleichzeitig 
geändert werden und das so programmiert ist. Dann muss ich für jeden Pin 
entsprechend Code abarbeiten. ... bedeutet keinerlei Einschränkung, 
sondern Flexibilität.)

Sobald der Prozessor die ISR verlässt, holt er sich die Adresse für den 
Code außerhalb der ISR und das Statusregister vom  Stack zurück und 
setzt seine ursprüngliche Bearbeitung weiter fort und zwar mit dem 
Globalen Interrupt Flag, das beim IRET wieder gesetzt wurde (erfolgt 
automatisch über Wiederherstellung des Stausregisters über das POP).

Sind jetzt zwischenzeitlich andere Interrupt Quellen zu anderen 
Vektoradressen zu anderen ISR aufgetreten, werden die in der Reihenfolge 
der Priorität angesprungen.

Eigentlich ist dieses Verfahren plausibel, einfach, logisch und somit 
straight forward, beim MSP430.

Bei Fragen, bitte fragen.

Weiterhin Happy Coding und Gruß

Bernd

von Peter D. (peda)


Lesenswert?

Willi schrieb:
> Dazu muss nur in der ISR per SEI-Befehl das Interupt-Enable Flag wieder
> gesetzt werden.

Wer das einmal versucht hat, versucht es in der Regel nie wieder.
Fast alle außer den Timerinterrupts löschen ihr Flag nicht automatisch, 
d.h. ein SEI bewirkt eine Rekursion bis zum Stacküberlauf. Und selbst 
beim Timerinterrupt ist man nicht vorm Stacküberlauf sicher, wenn das 
Intervall zu kurz gewählt ist. SEI in Interrupts ist ein ziemlich 
sicherer Weg, sich ein Bein zu stellen.
Es hat schon seine Berechtigung, warum viele andere MC-Hersteller 
Interruptlevel in Hardware implementieren.

von (prx) A. K. (prx)


Lesenswert?

honk schrieb:
> Das ist schon klar. Nichtsdestotrotz hat er Prioritäten, insofern muss
> man diese falsche Aussage richtigstellen.

Im heute üblichen Verständnis von Interruptsystemen wird der Begriff von 
Prioritäten als vom System her verschachtelbare und unterbrechbare 
Interrupts mit Prioritäten verstanden. Und zwar auch dann, wenn man 
nicht alle diese Worte mitschleppt.

Dass man den AVRs nachhelfen kann, indem man Interrupts in ISRs freigibt 
und die Prioritäten über kreative Nutzung der Interrupt-Enables 
rudimentär nachbildet, ändert nichts am üblichen Verständnis von 
Interruptsystemen.

Da die Prioritäten von AVRs eine völlig andere Baustelle sind, 
eigentlich nur einen auf weissem Rauschen basierenden Zufallsgenerator 
ersetzen, ist eine Betonung von deren Existenz eher irreführend als 
hilfreich (lies: es geht kaum anders als so wie bei den AVRs).

NB: Es gibt Systeme, die dieser Sprachregelung entsprechend grenzwertig 
sind. So haben ARM7 Cores eigentlich nur 2 Interrupt-Prioritäten, und 
das von ARM definierte Interruptsystem tut sich mit Verschachtelung 
etwas schwer. Viele ARM7 µCs besitzen aber dennoch einen zusätzlichen 
Interrupt-Controller, der mit Klimmzügen in der ISR für verschachtelbare 
und unterbrechbare Interrupts mit Prioritäten genutzt werden kann.

: Bearbeitet durch User
von Bernd B. (microwave-designer)


Lesenswert?

Peter D. schrieb:
> Feivel schrieb:
>> nachdem ISRy fertig ist, fängt:
>> - ISRx von vorne an?
>> - ISRx wird ab Unterbrechung abgearbeitet?
>> - ISRx wird nicht weiter behandelt?
>
> Es gibt nur eins davon, das sinnvoll und logisch ist.

Man kann auch unkompliziert antworten:

UNTERBRECHUNG heißt danach an der Stelle der Unterbrechung weitermachen. 
Eine ISR wird nie WÄHREND der Abarbeitung des OP-Codes aufgerufen! D.h. 
beim Interrupt wird erst der aktuelle Code fertig gemacht und dann 
verzweigt und bei Rückkehr weitergemacht, nichts wiederholt oder 
übersprungen.

Auch hier gibt es Möglichkeiten die Rücksprungadresse beim Verlassen der 
ISR zu verändern. Das würde aber über einen EXPLIZITEN Code innerhalb 
der ISR und befummeln des Stack erfolgen. Das machen nur die 
Programmierer, die es unbedingt wollen und ggf. mit Schmerzen leben 
können.

Gruß

Bernd

von (prx) A. K. (prx)


Lesenswert?

Bernd B. schrieb:
> Eine ISR wird nie WÄHREND der Abarbeitung des OP-Codes aufgerufen!

Zumindest ist das beim AVR nicht so. Tatsächlich gibt es diverse 
Architekturen, die bei einer anstehenden Interrupt-Anforderung eine 
Unterbrechung von bestimmten Befehlen mit längerer Laufzeit vorsehen.

Beispielsweise unterbrechen Befehle mit interner Schleife wie LDIR (Z80) 
oder MOVS (x86) und erledigen den verbleibenden Rest danach.

Manche Cores mit Fokus auf Mikrocontroller brechen im Interesse kurzer 
Interrupt-Latenz komplexe Befehle auch einfach ab und wiederholen die 
Ausführung danach vollständig.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Manche Cores mit Fokus auf Mikrocontroller brechen im Interesse kurzer
> Interrupt-Latenz komplexe Befehle auch einfach ab und wiederholen die
> Ausführung danach vollständig.
Hast du da eine Architektur dafür? Das sind aber dann hoffentlich nur 
"interne" Befehle, die keine Statusflags ändern...

von honk (Gast)


Lesenswert?

A. K. schrieb:
> honk schrieb:
>> Das ist schon klar. Nichtsdestotrotz hat er Prioritäten, insofern muss
>> man diese falsche Aussage richtigstellen.
>
> Im heute üblichen Verständnis von Interruptsystemen wird der Begriff von
> Prioritäten als vom System her verschachtelbare und unterbrechbare
> Interrupts mit Prioritäten verstanden. Und zwar auch dann, wenn man
> nicht alle diese Worte mitschleppt.


Auch das ist klar.
Problematisch ist halt nur, dass in den Atmel-Datenblättern das Wort 
Interruptpriorität eindeutig definiert ist, und zwar eben nicht so im 
"üblichen" Sinne.

von (prx) A. K. (prx)


Lesenswert?

Lothar M. schrieb:
> Hast du da eine Architektur dafür?

Die ARMv7-M Architektur der Cortex-Mx erlaubt beides:

"In the base ARMv7-M architecture the exception-continuable instructions 
are LDM, LDMDB, STM, STMDB, POP, and PUSH.
[...]
Alternatively, the processor can abandon the execution of a Load 
Multiple or Store Multiple instruction on taking an exception, and 
restart the instruction processing, from the start of the instruction, 
on returning from the exception."

: Bearbeitet durch User
von honk (Gast)


Lesenswert?

A. K. schrieb:
> Lothar M. schrieb:
>> Hast du da eine Architektur dafür?
>
> Die ARMv7-M Architektur der Cortex-Mx erlaubt beides:
>
> "In the base ARMv7-M architecture the exception-continuable instructions
> are LDM, LDMDB, STM, STMDB, POP, and PUSH.
> [...]
> Alternatively, the processor can abandon the execution of a Load
> Multiple or Store Multiple instruction on taking an exception, and
> restart the instruction processing, from the start of the instruction,
> on returning from the exception."


Und nicht mehr alternativ ist es bei SDIV/UDIV, die in jedem Fall neu 
ausgeführt werden.

von (prx) A. K. (prx)


Lesenswert?

Lothar M. schrieb:
> Das sind aber dann hoffentlich nur "interne" Befehle,
> die keine Statusflags ändern...

Abbrechbare oder unterbrechbare Befehle haben bisweilen eben deshalb 
Einschränkungen in der Kombination der Register, um damit keine Probleme 
zu bekommen.

Bei Architekturen mit Unterstützung virtuellen Speichers ist es 
allgemein üblich, dass Befehle abgebrochen und wiederholt werden. Nur 
Ausnahmen wie 68010 und 68020 verwendeten unterbrechbaren Microcode 
dafür, und das auch nur gezwungenermassen.

Der Trick besteht darin, unwiderrufliche Veränderungen erst dann 
durchzuführen, wenn der Fall nicht mehr auftreten kann. Was bei Out Of 
Order Architekturen nicht weiter schwierig ist.

Das betrifft zwar üblicherweise nur spezielle synchrone Exceptions und 
keine Interrupts, aber das Prinzip bleibt gleich und liesse sich auch 
auf asynchrone Exceptions wie Interrupts anwenden.

: Bearbeitet durch User
von Bernd B. (microwave-designer)


Lesenswert?

A. K. schrieb:
> Zumindest ist das beim AVR nicht so. Tatsächlich gibt es diverse
> Architekturen, die bei einer anstehenden Interrupt-Anforderung eine
> Unterbrechung von bestimmten Befehlen mit längerer Laufzeit vorsehen.

> Beispielsweise unterbrechen Befehle mit interner Schleife wie LDIR (Z80)
> oder MOVS (x86) und erledigen den verbleibenden Rest danach.

... da haben wir sie wieder, die Farbe des Bartes vom Kaiser!

Smiley!

Bernd

Anhang:
http://www.worldofspectrum.org/Z80.html
Here's an example of block shift:
1
Here's an example of block shift:
2
3
   LD DE,0000h
4
   LD HL,4000h
5
   LD BC,0100h
6
   LDIR

Can you see how this works? Basically 100h bytes of data starting at 
4000h are copied to 0000h through to 0100h. Block shift is useful in a 
text editor for example. You might want to delete a character and then 
shift everything else down in memory. Block shift will do that quickly 
and easily. You can think of it as a copy instruction.

von Wolfgang (Gast)


Lesenswert?

Hubertus schrieb:
> Beim AVR sind wimre alle Interrupts gleich priorisiert und können sich
> somit nicht unterbrechen.

Das stimmt doch nicht.
Jedem Programmierer steht es frei, in seiner ISR gleich zu Anfang 
Interrupts wieder frei zu geben, so dass auch ein anderer IRQ zum Zuge 
kommen kann. Das setzt allerdings etwas Umsicht bei der Formulierung der 
ISR voraus.

von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

> Fast alle außer den Timerinterrupts löschen ihr Flag nicht automatisch,

Es stimmt, dass es solche Interupts gibt, aber es stimmt sicher nicht, 
dass es "fast alle" wären. Tatsächlich sind es nämlich nur ganze drei:

2x USART (RXC und UDRE) und 1x TWI (TWINT).

Richtig ist also: bei fast allen Interrupts wird das Flag automatisch 
gelöscht.

Nochmal zu Verdeutlichung: Der Mega644P z.B. hat 30 Interruptvektoren. 
Nur 3 davon löschen nicht automatisch das auslösende IRQ-Flag, das sind 
exakt 10%.

"Fast alle"? Lächerlich.

Du gibst mir 90% deines Einkommens, sollte ja kein Problem sein, da du 
ja "fast alles" behalten darfst...

von Theor (Gast)


Lesenswert?

Nun gut. Wir wissen alle, dass es da eine ganze Reihe verschiedener 
Varianten gibt. Da können wir uns noch Tage damit vergnügen uns 
gegenseitig mit noch einer Geschmacksrichtung zu "überraschen" oder die 
Vorzüge dieses oder jenes Systems zu preisen.

Es sprechen allerdings ein oder zwei Anhaltspunkte dafür, dass der TO 
lediglich eine Frage im Unterricht beantworten, bzw. ein Referat halten 
muss. Und dafür wurden ihm die wesentlichen Punkte schon erklärt, denke 
ich.

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Richtig ist also: bei fast allen Interrupts wird das Flag automatisch
> gelöscht.

Wobei das spezifisch für AVRs gilt. Andere Controller, andere Sitten.

von c-hater (Gast)


Lesenswert?

A. K. schrieb:

> Wobei das spezifisch für AVRs gilt. Andere Controller, andere Sitten.

Natürlich, keine Frage.

Der Trick ist halt immer derselbe: man muß schlicht wissen, was man tut. 
Und die Grundlage dafür ist solides Faktenwissen über die jeweilige 
Zielarchitektur. Und offensichtliche Falschaussagen können nunmal nix 
dazu beitragen, solches Grundlagenwissen zu schaffen, auch dann nicht, 
wenn sie nur ein bestimmte Architektur falsch beschreiben. Deswegen muss 
man ihnen einfach widersprechen.

von Willi (Gast)


Lesenswert?

Peter D. schrieb:
> Willi schrieb:
>> Dazu muss nur in der ISR per SEI-Befehl das Interupt-Enable Flag wieder
>> gesetzt werden.
>
> Wer das einmal versucht hat, versucht es in der Regel nie wieder.
> Fast alle außer den Timerinterrupts löschen ihr Flag nicht automatisch,
> d.h. ein SEI bewirkt eine Rekursion bis zum Stacküberlauf. Und selbst
> beim Timerinterrupt ist man nicht vorm Stacküberlauf sicher, wenn das
> Intervall zu kurz gewählt ist. SEI in Interrupts ist ein ziemlich
> sicherer Weg, sich ein Bein zu stellen.

Genau solche Aussagen führen dazu, dass Interupts hier immer wie eine 
Art Mysterium behandelt werden. Das Freigeben von weiteren Interrupts 
ist der einzig mögliche und durchaus zulässige Weg, verschachtelte 
Interrupts beim AVR zu realisieren. Jeder neue Interrupt setzt das 
INT-Flag wieder zurück und sperrt damit weitere Interrupts. Deshalb gibt 
es nicht automatisch eine Rekursion. Das ist alles vorherseh- und 
beherrschbar. Du beschreibst es so, als kämen irgendwelche Interrupts 
heimlich und unerwartet um die Ecke geschlichen. Aber das hat man doch 
alles selbst programmiert, und sollte man im Griff haben. Und wenn das 
"Intervall zu kurz ist", dann ist das einfach ein Programmierfehler. Und 
nichts Überraschendes oder Geheimnisvolles.

Anstatt sich hinter sochen Aussagen oder der hier häufig verbreiteten 
Falschmeldung "ISR sollen IMMER so kurz wie möglich sein" zu verstecken, 
macht es mehr Sinn, sich mit dem Datenblatt des Controllers auseinander 
zu setzen, um wirklich zu verstehen, was bei Interrupts abläuft. Dann 
kann man sie auch ohne "geheimnisvolle Fallen" sinnvoll einsetzen, und 
damit die Leistungsfähigkeit des AVR auch nutzen.

Feuer frei und Grüsse

Willi

von c-hater (Gast)


Lesenswert?

Willi schrieb:

> Aber das hat man doch
> alles selbst programmiert, und sollte man im Griff haben.

Falsch. Das gilt nämlich leider NICHT für Interrupts aus externen 
Quellen. Ganz sicher jedenfalls nicht für diejenigen, die das Potential 
haben, schneller Interrupts auszulösen, als man sie selbst im Idealfall 
einer sinnvollen Konfiguration und mit optimiertem Assembler in der ISR 
behandeln könnte.

Und das sind tatsächlich einige: INTx, PCINTx, ICPx, ACI z.B.

Darauf hat nichtmal der allerbeste Assemblerprogrammierer irgendeinen 
Einfluss. DoS über einen wildgewordenen Interrupteingang ist also immer 
möglich. Das Problem ist nur durch drei Ansätze lösbar

1) Das kann nicht passieren. (Sprich: man stellt sicher, das die 
abzufragende/zu beobachtende Peripherie sowas niemals liefern würde)

2) Durch zusatzliche Hardware (Tiefpässe), die die maximale 
Interruptrate zuverlässig auf vertretbare Werte absenken kann.

3) durch Verzicht auf Interrupts aus dieser Quelle und Ersatz durch 
Polling.

von Willi (Gast)


Lesenswert?

Ja, da stimme ich dir zu, das externe INTs womöglich völlig asynchron 
und häufiger als einem lieb ist, auftreten können. Das wird dann 
schwierig.
Einige mögliche Lösungen hast du ja schon angedeutet.

Mir geht es aber darum, das auch solche externe Interruptquellen vorher 
bekannt sind. Ihre womöglich unschönen Eigenschaften sind nicht 
unvorhersehbar und überraschend. Da muss man sich eben informieren, mit 
was da zu rechnen ist, und sich ein Konzept überlegen, wie und ob man 
damit klarkommt.
Der Fall, das man gar nicht weiss was da kommt, und mit allem klarkommen 
muss, was auch immer es ist, entspricht wohl nicht der Praxis.


MfG Willi

von Thomas E. (picalic)


Lesenswert?

c-hater schrieb:
> 1) ...
>
> 2) ...
>
> 3) ...

und
Willi schrieb:
> häufiger als einem lieb ist, auftreten können. Das wird dann
> schwierig.

es gibt auch noch die Möglichkeit, das Interrupt Enable Bit für die 
entsprechende Hardware in der ISR zurückzusetzen:
(x feuert Interrupt)
 -> Eintritt in die ISR, global Interrupt disabled
 - Interrupt disable für Peripherie (x)
 - global Interrupt enable
   -> (jetzt können andere Quellen nested Interrupts auslösen, x aber 
nicht)
 - ISR code für (x) ausführen
 - globalen Interrup disablen
 - ggf. Interrupt-Flag (x) löschen
 - Interrupt enable für Peripherie (x)
 <- Return from Interrupt (dabei wird der globale Interrupt enabled)

: Bearbeitet durch User
von Ymega! (Gast)


Lesenswert?

Ein Xmega ist auch ein AVR, aber da sind die Interrupts unterbrechbar, 
AFAIK.

von willi (Gast)


Lesenswert?

Thomas E. schrieb:
> es gibt auch noch die Möglichkeit, das Interrupt Enable Bit für die
> entsprechende Hardware in der ISR zurückzusetzen:
> (x feuert Interrupt)
>  -> Eintritt in die ISR, global Interrupt disabled
>  - Interrupt disable für Peripherie (x)
>  - global Interrupt enable
>    -> (jetzt können andere Quellen nested Interrupts auslösen, x aber
> nicht)
>  - ISR code für (x) ausführen
>  - globalen Interrup disablen
>  - ggf. Interrupt-Flag (x) löschen
>  - Interrupt enable für Peripherie (x)
>  <- Return from Interrupt (dabei wird der globale Interrupt enabled)

Ja richtig, sowas kann man machen.

Das gesamte Interruptsystem des AVR steht komplett unter Kontrolle des 
Programmierers.
Da passiert nichts unvorhersehbares oder geheimnisvolles.
So muss es ja auch sein, die Designer des AVR waren doch keine Anfänger.

Und nochmal: Die AVR Interrupts sind unterbrechbar. Wenn man das will.

MfG Willi

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.