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
https://www.mikrocontroller.net/articles/Interrupt#Verschachtelte_Interrupts Kommt auf deinen Controller an
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.
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.
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
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...
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
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)
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.
Wieder was gelernt... ich bedanke mich recht herzlich!
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.
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
> 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
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.
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.
@ 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.
Es gibt nicht neues unter der Sonne. https://www.mikrocontroller.net/articles/Interrupt#Verschachtelte_Interrupts
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 ;)
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.
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
Falk B. schrieb: > Die C2000 (PICCOLO) von TI haben das auch nicht. Gibts da mal was was deine geliebten PICCOLO nicht können ;)?
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.
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.
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
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 ;)
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.
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... ;-)
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
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.
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
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
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
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...
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.
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
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.
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
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.
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.
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...
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.
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.
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.
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
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.