Hallo, werden Interrupts eigentlich gespeichert, solange diese noch nicht ausgeführt worden sind? (In meinem Fall für einen Atmega328) Wie verhält es sich, wenn ich eine Interruptroutine für eine Steigende und fallende Flanke erstelle (z.B. von einem Button (Prellen vernachlässige ich jetzt mal)) Wenn ich diesen Button sehr schnell drücke, sodass ein Interrupt ausgelöst wird, obwohl die erste Interrupt-Routine noch nicht fertig ist, wird diese danach wider ausgelöst? Wie viele Interrupts können gespeichert werden? Was passiert wenn ich ein Delay habe (nehmen wir mal an 5 Sekunden) und ich drücke während des Delays den Button ein paar mal. Wird der Interrupt auch ausgelöst? Es ist nicht so, dass ich diese Probleme habe (vor allem nicht mit dem Delay), es interessiert mich nur, wie soetwas vom uC gehändelt wird. Gruß Johannes
Naja das hängt halt maßgeblich im Prozessor ab. Normalerweise gibt es eine IRQ-Priorisierung. Die gibt an, welcher Interrupt welchen unterbrechen darf. Wieviele Prios es gibt, hängt vom Prozessor ab. Ein Prio-1 IRQ kann einen Prio-2 überfahren. Dann bleibt die Prio-2-ISR einfach stehen, die Prio 1 wird ausgeführt, und zurück in die 2er gesprungen. Es gibt aber auch asynchrone Interrupts, da wird dann nicht zwangsläufig unterbrochen bzw. hängt es vom Programmierer ab, ob der das möchte. Wenn bereits eine ISR am laufen ist, und es wird ein IR mit gleicher Prio gefeuert, dann geht der IRQ m.W.n. verloren. Es wäre aber auch irgendwie merkwürdig, warum zweimal der gleiche IR gefeuert werden sollte. Deshalb gilt es auch, die ISR möglichst schlank zu halten, und alles zeitaufwändige Handling in eine eigene, im regulären Programmablauf befindliche Routine zu bearbeiten, die je nach Prozessor dann synchron oder asynchron abgearbeitet werden kann.
Beitrag #5181457 wurde von einem Moderator gelöscht.
Konkret auf deinen Atmega328 bezogen: Nein, der hat keine Möglichkeit Interrupts zu schachteln bzw zu speichern. Wenn du deine aktuelle Interrupt-Routine nicht abschließt, bevor ein neuer Interrupt geht der neue Interrupt "verschütt". Daher gelten die oben genannten Prinzipien.
Beitrag #5181461 wurde von einem Moderator gelöscht.
Stefan S. schrieb: > Konkret auf deinen Atmega328 bezogen: Nein, der hat keine Möglichkeit > Interrupts zu schachteln Nicht von sich aus, nein. Aber man kann sehr wohl die Interrupts im Interrupt wieder freigeben.
Martin S. schrieb: > Wenn bereits eine ISR am laufen ist, und es wird ein IR mit gleicher > Prio gefeuert, Das wird er nicht - jedenfalls nicht bei den Prozessoren, die ich kenne. Wenn der Prozessor sich in einer Interruptroutine befindet, werden die Interrupts dieser Prioritätsebene (und aller niedrigeren) normalerweise gesperrt. Das "auslösende" Device hat üblicherweise nur ein Flag, um anzuzeigen, was genau passiert ist und kann das nicht unterbringen, solange der "alte" Interrupt noch nicht fertig abgearbeitet ist. Es gibt Prozessoren, wo in dieser Situation (Interruptmaske fälschlicherweise vor der Beendigung des Interrupts "aufgemacht") ein "spurious Interrupt" ausgelöst wird.
> Wird ein Interrupt gespeichert? > für einen Atmega328) @Johannes @Martin @Stefan Was ist so schwer daran die Docu zu lesen? https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0ahUKEwjTyO6Kwf7WAhUL1RoKHTGVBmQQFghuMAE&url=http%3A%2F%2Fwww.atmel.com%2Fimages%2FAtmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf&usg=AOvVaw1737uYd3aLQvvobeVtfUHP Wozu hat der MC wohl so viele "Interrupt Flag Register"?
Johannes schrieb: > Was passiert wenn ich ein Delay habe (nehmen wir mal an 5 Sekunden) Wenn du ein delay(x) im Programm hast, hast du einfach ein beschissenes Programm!
:
Bearbeitet durch User
Hier ist es gut erklärt: http://www.physik.uni-regensburg.de/studium/edverg/elfort/C_KURS_Atmel_Programmieren/Interrupts.htm
Max M. schrieb: > Wenn du ein delay(x) im Programm hast, hast du einfach ein beschissenes > Programm! Aber den Interrupts ist das wurscht - die werden trotzdem ausgeführt. _delay_ms() und _delay_us() blockieren keine Interrupts.
:
Bearbeitet durch User
Max M. schrieb: >> Wird ein Interrupt gespeichert? > >> für einen Atmega328) > > @Johannes > @Martin > @Stefan > > Was ist so schwer daran die Docu zu lesen? Ach richtig. Ich vergaß ja vollkommen, dass es nur einen einzigen Prozessor auf der Welt gibt... (Sag mal - liest Du Dir eigentlich auch durch, was du schreibst?)
Wenn der TO nunmal nach einem AtMega fragt, was nutzt dann eine Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest? Oliver P.s. 42
Oliver S. schrieb: > Wenn der TO nunmal nach einem AtMega fragt Ich verstand seine Frage als grundsätzlich, mit fernen Bezug auf seinen Atmega. Daher ist die Antwort weder falsch noch unpassend.
Martin S. schrieb: > Daher ist die Antwort weder falsch noch unpassend. Und völlig ohne sachdienlichen Inhalt
Johannes schrieb: > werden Interrupts eigentlich gespeichert, solange diese noch nicht > ausgeführt worden sind? Das widerspricht dem Sinn eines Interrupts. Die sollen ja gerade das laufende Programm unterbrechen (Interrupt == Unterbrechung). Natürlich kannst Du innerhalb eines Interrupts eine Art Speicherung einbauen. Im Falle Deines Buttons könntest Du z.B. den Tastendruck in einen Puffer schreiben. Wenn Du eine längere Aufgabe bearbeitest oder schläfst, dann unterbricht Dein Körper trotzdem automatisch alle 2 Sekunden, um zu atmen. Das geschieht meistens unbewusst. Und genau wie bei Interrupts ist es auch hier nicht sinnvoll, das Atmen für 2 Stunden einzustellen und danach 3600 Atemzüge nachzuholen. Viele Grüße, Stefan
Matthias S. schrieb: > Max M. schrieb: >> Wenn du ein delay(x) im Programm hast, hast du einfach ein beschissenes >> Programm! > > Aber den Interrupts ist das wurscht - die werden trotzdem ausgeführt. > _delay_ms() und _delay_us() blockieren keine Interrupts. Wenn sie in der Interruptfunktion stehen schon. ;-) Das ist ja bei Anfängern nicht unbedingt ausgeschlossen.
Dussel schrieb: > Wenn sie in der Interruptfunktion stehen schon. ;-) Das ist ja bei > Anfängern nicht unbedingt ausgeschlossen. delay in einer ISR wird normalerweise vom Compiler ignoriert!
Beim Atmega328 könnte man das Setzen des Interrupt Flags als Speichern eines Interrupts bezeichnen. Tritt ein Interrupt auf und tritt während der Ausführung der Interruptserviceroutine ein weiter gleicher Interrupt auf wird das Flag gesetzt und speichert diesen Interrupt solange bis es manuell oder durch die entsprechende ISR automatisch gelöscht wird. Ein zwei gleiche Interrupts werden so nicht gespeichert, da nur jeweil ein Flag vorhanden ist. Mehrere andere Interrupts können mit den entsprechenden Flags gespeichert werden und werden mit den zugehörigen ISRs nacheinander abgearbeitet wenn keine andere ISR läuft, sie an der Reihe sind und keine besondere Programmiermaßnahmen getroffen wurden. Level Interrupts werden so nicht gespeichert, da da kein Flag gesetzt wird.
Max M. schrieb: > Dussel schrieb: >> Wenn sie in der Interruptfunktion stehen schon. ;-) Das ist ja bei >> Anfängern nicht unbedingt ausgeschlossen. > delay in einer ISR wird normalerweise vom Compiler ignoriert! Wo hast du denn diese schlaue Weisheit her?
:
Bearbeitet durch Moderator
Aber mit SEI in ISR kann man schön in Teufels Küche kommen ... ISR kurz, kürzer, am kürzesten halten
wer delay benutzt hat noch nicht die nötige Reife für Interrupts.
Volle schrieb: > wer delay benutzt hat noch nicht die nötige Reife für Interrupts. Pauschale Aussagen sind immer falsch. :-)
Martin S. schrieb: > Daher ist die Antwort weder falsch noch unpassend. Im Bezug auf den AtMega ist die Antwort in vielen Punkten sachlich falsch. Oliver
Volle schrieb: > wer delay benutzt hat noch nicht die nötige Reife für Interrupts. Wer das so pauschal behauptet, hat auch keine nötige Reife.
Matthias S. schrieb: > _delay_ms() und _delay_us() blockieren keine Interrupts. Für die beiden gilt das... Am Rande: In meiner kleinen Arduino Welt, benötigt delay() selber Interrupts, so dass man sich in einer ISR, auf die Art, fix mal eben einen Deadlock einfängt.
Johannes schrieb: > werden Interrupts eigentlich gespeichert, solange diese noch nicht > ausgeführt worden sind? Wie schon geschrieben, es wird nichts gespeichert solange die ISR nicht aufgerufen wurde. Aber ein laufender Interrupt kann durchaus von einem anderen unterbrochen werden. Der Status wird über den Stack gespeichert, und wenn der spätere Interrupt abgearbeitet ist, wird die erste Routine wieder aufgenommen. Dabei besteht aber offensichtlich die Gefahr eines stack overflows. Google einfach nach "atmega nested interrupts", es gibt jede Menge tutorials und diskussionen hierzu.
Klaus P. schrieb: > Aber ein laufender Interrupt kann durchaus von einem anderen > unterbrochen werden. Beim AVR ist das standardmäßig erst einmal nicht der Fall; beim Eintritt in eine ISR löscht die Hardware das I-Flag, dieses wird normalerweise dann durch RETI wieder gesetzt. Es ist natürlich unbestritten, dass man das I-Flag auch selbst in der ISR setzen kann; dann sollte man aber sehr genau wissen, was man tut. Der schon genannte Ratschlag, die ISRs so kurz wie möglich zu halten, ist gemeinhin die bessere Methode. Dass man irgendwelche manuell betätigten Taster gar nicht erst interrupten lässt, ist eine völlig andere Sache. Mensch und Mechanik sind langsam genug, als dass man das völlig unproblematisch in einem regelmäßigen Timerinterrupt abfragen kann, der dann auch gleich die Entprellung erledigt. Ausnahme: ein Interrupt durch einen Taster, mit dem die MCU aus dem Schlaf geweckt wird. Dann ist aber die erste Amtshandlung der ISR, den Taster als Interruptquelle sofort abzuschalten.
Dussel schrieb: >> Aber den Interrupts ist das wurscht - die werden trotzdem ausgeführt. >> _delay_ms() und _delay_us() blockieren keine Interrupts. > Wenn sie in der Interruptfunktion stehen schon. ;-) Das ist ja bei > Anfängern nicht unbedingt ausgeschlossen. Nö, das ist Quak. Die Delay Routinen der avrlibc lassen während ihrer Ausführung ganz normal alle freigegebenen Interrupts zu, ob sie nun in der ISR stehen oder nicht. Das das Delay dann nicht mehr stimmt, ist eine andere Sache. Wenn man es explizit tut, kann man auch andere Interrupts innerhalb einer ISR auch wieder zulassen, der AVR sperrt zwar während der Abarbeitung einer ISR das globale ISR Flag, aber niemand hindert einen daran, es in der ISR wieder freizugeben. (avrlibc sieht dazu das 'ISR_NOBLOCK' vor). Aha, da war Jörg schneller. Die Priorität ist beim AVR festgelegt und zwar absteigend mit den IRQ Vektoren. D.H. die höchste Priorität hat Reset, im Allgemeinen folgt dann INT0, siehe Vektortabelle.
:
Bearbeitet durch User
Matthias S. schrieb: > Die Priorität ist beim AVR festgelegt und zwar absteigend mit den IRQ > Vektoren. Die spielt allerdings nur eine Rolle, um festzulegen, welche ISR zuerst bedient wird, wenn beim Freigeben der Interrupts (SEI) mehr als ein Interrupt bereits anhängig ist. Wenn man innerhalb einer ISR die Interrupts freigibt, dann dürfen wiederum alle weiteren Interrupts diese ISR unterbrechen.
Oliver S. schrieb: > Martin S. schrieb: >> Daher ist die Antwort weder falsch noch unpassend. > > Im Bezug auf den AtMega ist die Antwort in vielen Punkten sachlich > falsch. Wo? Ausschließlich die Frage Synchron/Asynchron passt zum Mega nicht. Sonst?
Martin S. schrieb: > Normalerweise gibt es eine IRQ-Priorisierung. Hat der AtMega nicht. > Es gibt aber auch asynchrone Interrupts. Hat der AtMega nicht. > > Wenn bereits eine ISR am laufen ist, und es wird ein IR mit gleicher > Prio gefeuert, dann geht der IRQ m.W.n. verloren. Es wäre aber auch > irgendwie merkwürdig, warum zweimal der gleiche IR gefeuert werden > sollte. Die erste Aussage ist für den AtMega (und sehr viele ander Prozessoren) falsch, die zweite sowieso. > Deshalb gilt es auch, die ISR möglichst schlank zu halten, und alles > zeitaufwändige Handling in eine eigene, im regulären Programmablauf > befindliche Routine zu bearbeiten, die je nach Prozessor dann synchron > oder asynchron abgearbeitet werden kann. Ok Kein sehr guter Schnitt... Oliver
Jörg W. schrieb: > Die spielt allerdings nur eine Rolle, um festzulegen, welche ISR > zuerst bedient wird, wenn beim Freigeben der Interrupts (SEI) mehr > als ein Interrupt bereits anhängig ist. Soweit ich weiss, würde es auch dann wichtig sein, wenn zwei IRQs gleichzeitig eintreffen. Arduino F. schrieb: > In meiner kleinen Arduino Welt, benötigt delay() selber Interrupts Das tut mir leid. Aber da ist euch wohl der Ticker mit seinen millis() o.ä. im Weg. Das kann natürlich mal blöd sein. Aufm STM32 hatte ich mal den Delay mit Systick() in einer Elektromagnet-Bedien ISR. Da hing er dann, bis ich die Prioritäten umgeschnurzelt hatte und Systick() wichtiger machte. Das geht aufm AVR nicht, Timer 0 (oder was auch immer da triggert) ist ziemlich weit hinten.
:
Bearbeitet durch User
Matthias S. schrieb: > Das tut mir leid. Danke, aber dafür gibts keinen Grund. Es reicht, wenn man es weiß, und es sein lässt.
Martin S. schrieb: > Es gibt aber auch asynchrone Interrupts, da wird dann nicht zwangsläufig > unterbrochen bzw. hängt es vom Programmierer ab, ob der das möchte. Synchrone Interrupts stehen in direktem Zusammenhang mit dem Befehlsablauf. Sowas wie Division durch 0 fällt darunter. Werden oft auch zwecks Unterscheidung als Traps oder Exceptions bezeichnet. Asynchrone Interrupts werden von Ereignissen ausgelöst, die mit dem Befehlsablauf nichts zu tun haben. Das sind die üblichen Hardware-Interrupts durch Timer, UART etc.
Oliver S. schrieb: >> Es gibt aber auch asynchrone Interrupts. > Hat der AtMega nicht. Er hat nur asynchrone Interrupts, aber keine synchronen.
Matthias S. schrieb: > Jörg W. schrieb: >> Die spielt allerdings nur eine Rolle, um festzulegen, welche ISR >> zuerst bedient wird, wenn beim Freigeben der Interrupts (SEI) mehr >> als ein Interrupt bereits anhängig ist. > > Soweit ich weiss, würde es auch dann wichtig sein, wenn zwei IRQs > gleichzeitig eintreffen. Das stimmt zwar, dürfte aber in der realen Welt seltener als ein Sechser im Lotto sein. :)
Dazu braucht es nur zwei Timer. Deren Interrupts können sich regelmäßig treffen. Oliver
Oliver S. schrieb: > Martin S. schrieb: >> Normalerweise gibt es eine IRQ-Priorisierung. > > Hat der AtMega nicht. Der Atmega2560 hat sogar 12 Interruptvektoren. >> Es gibt aber auch asynchrone Interrupts. > > Hat der AtMega nicht. Zitat: External interrupts can be sensed and registered either synchronously or asynchronously. Synchronous sensing requires I/O clock whereas asynchronous sensing does not requires I/O clock. This implies that the interrupts that are detected asynchronously can be used for waking the device from sleep modes other than idle mode because the I/O clock is halted in all sleep modes except idle mode. The sense configuration for external interrupts and pin change interrupts for Atmel ATmega2560 is given in Table 1-2 External Interrupts Sense Configuration. For device specific sense configuration, refer to the respective datasheet. Sowie: Asynchronous Sensing in ATmega2560 From Table 1-2 External Interrupts Sense Configuration interrupts INT3:0 are registered asynchronously. Pulses on INT3:0 pins wider than the minimum pulse width (typically 50ns for ATmega2560) will generate an interrupt. Shorter pulses are not guaranteed to generate an interrupt. Synchronous Sensing in ATmega2560 From Table 1-2 External Interrupts Sense Configuration, interrupts INT7:4 are registered synchronously. The value on the INT7:4 pins are sampled before detecting edges. If edge or toggle interrupt is selected, pulses that last longer than one clock period will generate an interrupt. Shorter pulses are not guaranteed to generate an interrupt. For both types of sensing, if low level interrupt is selected, the low level must be held until the completion of the currently executing instruction to generate an interrupt. >> Wenn bereits eine ISR am laufen ist, und es wird ein IR mit gleicher >> Prio gefeuert, dann geht der IRQ m.W.n. verloren. Es wäre aber auch >> irgendwie merkwürdig, warum zweimal der gleiche IR gefeuert werden >> sollte. > > Die erste Aussage ist für den AtMega (und sehr viele ander Prozessoren) > falsch, die zweite sowieso. Zitat: Interrupt Priority Priority for the interrupts is determined by the interrupt vector address. An interrupt with lowest interrupt vector address has the highest priority. So reset has the highest priority followed by INT0, then INT1 and so on. If two interrupts occurs simultaneously, then the interrupt with higher priority is served first. Sowie Once the CPU enters the ISR, the global interrupt enable bit (I-bit) in SREG will be cleared so that all other interrupts are disabled. In order to use nested interrupts, the I-bit has to be set by software when the CPU enters an ISR. >> Deshalb gilt es auch, die ISR möglichst schlank zu halten, und alles >> zeitaufwändige Handling in eine eigene, im regulären Programmablauf >> befindliche Routine zu bearbeiten, die je nach Prozessor dann synchron >> oder asynchron abgearbeitet werden kann. > > Ok > > Kein sehr guter Schnitt... Gelle?! Das denke ich mir doch auch ;-) Fairerweise muss man sagen, dass diese Aussagen nicht zwangsläufig auf den Mega des TO zutrifft, aber Du hast ja prinzipiell in Frage gestellt, dass der Atmega das überhaupt kann / hat. Im Zweifelsfalle steht vermutlich kaum was anderes in den jeweiligen Datenblättern, weil o.g. seit 30 Jahren Standard ist.
:
Bearbeitet durch User
Martin S. schrieb: >>> Normalerweise gibt es eine IRQ-Priorisierung. >> >> Hat der AtMega nicht. > > Der Atmega2560 hat sogar 12 Interruptvektoren. Bei Priorisierung von Interrupts können hoch priorisierte Interrupts niedriger priorisierte Interrupt-Handler unterbrechen. Die bei AVRs vorhandene Entscheidung, welcher Vektor bei mehreren anstehenden Interrupts angesprungen wird, versteht man darunter üblicherweise nicht. AVRs Vektoren sind priorisiert, die Interrupts an sich aber nicht. > External interrupts can be sensed and registered either synchronously or > asynchronously. Atmel schreibt hier "synchronous sensing", nicht "synchronous interrupt". Wenn man genau sein und Missverständnisse vermeiden will, kann man notfalls dazuschreiben, auf was genau man sein "(a)synchron" bezieht. Ob auf den Befehlsfluss oder die Taktversorgung. Es kann sich lohnen, das Blickfeld etwas über AVRs hinaus zu erweitern, auch wenn es in einem Thread um AVRs geht. Das vermeidet Missverständnisse, was typübergreifende Begriffe und proprietäre Formulierungen betrifft.
:
Bearbeitet durch User
Matthias S. schrieb: >> Die spielt allerdings nur eine Rolle, um festzulegen, welche ISR >> zuerst bedient wird, wenn beim Freigeben der Interrupts (SEI) mehr >> als ein Interrupt bereits anhängig ist. > > Soweit ich weiss, würde es auch dann wichtig sein, wenn zwei IRQs > gleichzeitig eintreffen. Beides oder weder noch. Bei eingeschalteten Interrupts entscheidet der Prozessor an einer bestimmten Stelle der Schritte der Abarbeitung anhand der zu diesem Zeitpunkt anstehenden Interrupt-Anforderungen über den Vektor. Entscheidend ist somit nicht, wie gleichzeitig sie eintreffen, sondern welche Interrupt-Anforderungen zu genau diesem Zeitpunkt aktiv sind. Man kann das noch feiner runterbrechen, indem man zwischen dem Zeitpunkt der Entscheidung, überhaupt einen Interrupt auszuführen, und der Entscheidung über den dafür genutzten Vektor unterscheidet. Das muss sich nicht decken, beispielsweise wenn die Entscheidung über den Vektor erst unmittelbar davor getroffen wird, was mehr oder weniger deutlich nach dem Stack-Push vom PC geschehen kann.
:
Bearbeitet durch User
Beim AVR ist das Interrupt-Handling eigentlich sehr einfach: Jeder Interrupt hat ein eigenes Interrupt-Flag (ein paar Ausnahmen gibt's allerdings). Wenn die Bedingung für den Interrupt eintritt, wird dieses Flag gesetzt. Das ist die eine Seite. Auf der anderen steht dann die Auslösung des Interrrupts. Die ist von drei Flags abhängig, nämlich besagtem Interrupt-Flag, dem Interrupt-Enable-Flag für diesen Interrupt und dem globalen Interrupt-Enable im SREG. Sind alle drei gesetzt, wird der Interrupt ausgelöst. Dabei wird automatisch das globale Interrupt-Enable und das Interrupt-Flag wieder gelöscht. Nach der ISR wird das globale Interrupt-Enable beim Rücksprung per RETI wieder automatisch gesetzt. Sobald die Bedingung wieder eintritt, wird das Interrupt-Flag wieder gesetzt, egal ob man gerade in der ISR ist oder in einer anderen ISR, oder ob der Interrupt gerade aus einem anderen Grund ausgeschaltet ist oder nicht. Der Interrupt wird dann auch wieder ausgelöst, sobald alle drei Flags gesetzt sind. Matthias S. schrieb: > Jörg W. schrieb: >> Die spielt allerdings nur eine Rolle, um festzulegen, welche ISR >> zuerst bedient wird, wenn beim Freigeben der Interrupts (SEI) mehr >> als ein Interrupt bereits anhängig ist. > > Soweit ich weiss, würde es auch dann wichtig sein, wenn zwei IRQs > gleichzeitig eintreffen. Ganz allgemein: Wenn für zwei (oder mehr) Interrupts der Fall, dass die drei Flags alle gesetzt sind, im selben Taktzyklus auftritt.
Martin S. schrieb: > Der Atmega2560 hat sogar 12 Interruptvektoren. Hat der nicht, der hat 57. Es macht ja nichts, daß du bisher noch nie mit den AtMegas zu tun hattest, aber so deutlich musst du es ja nicht zeigen. Die Dinger sind nunmal in vielem sehr viel einfacher gestrickt als „richtige“ Mikrocontroller. Oliver
Rolf M. schrieb: > Ganz allgemein: Wenn für zwei (oder mehr) Interrupts der Fall, dass die > drei Flags alle gesetzt sind, im selben Taktzyklus auftritt. Nicht unbedingt. Wenn sich die von mir vorhin genannten zwei Zeitpunkte nicht decken, dann kann es vorkommen, dass ein Handler angesprungen wird, dessen Interrupt-Anforderung erst einen oder mehrere Takte nach dem ersten der beiden Interrupts eintrudelte. Der erste Interrupt hat dann zwar den Prozessor aus der Bahn geworfen und führte zur Einleitung des Interrupt-Verfahren, aber der Vektor des zweiten Interrupts wird angesprungen. Noch krasser ist das bei Cortex M, bei denen eine bereits getroffene Vektor-Entscheidung ggf. wieder rückgängig gemacht wird, wenn ein höherer Interrupt noch vor dem ersten Befehl des Handlers reinkommt. Zudem geht es bei den meisten Prozessoren nicht so sehr um Taktzyklen, sondern um Befehlszyklen. Wenn die Entscheidung, ein Interrupt-Verfahren einzuleiten, in an einer bestimmten Stelle in der Befehlsbearbeitung erfolgt, nicht in jedem Takt. Da gibts freilich Ausnahmen, manchmal sind Befehle mit langer Laufzeit unterbrechbar.
A. K. schrieb: > Das muss sich nicht decken, beispielsweise wenn die Entscheidung über > den Vektor erst unmittelbar davor getroffen wird, was mehr oder weniger > deutlich nach dem Stack-Push vom PC geschehen kann. Um das zu wissen, müsste man wohl in den Verilog-Code reingucken. ;-) Aber jetzt wird es allmählich schon fast Haarspalterei.
Rolf M. schrieb: > Dabei wird automatisch das globale > Interrupt-Enable und das Interrupt-Flag wieder gelöscht. Mit ein paar wenigen Ausnahmen, z.B. wird das RXC Flag des Uarts erst beim Lesen des Uart-Data-registers UDR gelöscht. Genauso sieht es beim UART Transmitter aus. Das UDRE Flag wird erst dann gelöscht, wenn ein neues Zeichen in UDR zum Versenden geschrieben wird. Das ermöglicht z.B. beim Senden mit Handshake, im TXD-ISR zuerst die Handshake-leitung zu testen. Ist diese busy, dann wird der TXD-ISR disabled (UDRIE) und der ISR ohne das Senden eines Zeichens verlassen. Irgendwo anders (Timer-ISR) kann jetzt zyklisch das Handshake getestet werden. Bei Handshake=ready wird UDRIE wieder gesetzt und dadurch der TXD-ISR erneut ausgeführt. In diesem Fall "merkt" sich das ISR-Flag tatsächlich den Zustand. Ab dem Zeitpunkt, an dem das lokale ISR-Flag gelöscht wurde, kann auch die nächste ISR-Anforderung dieser Quelle registriert werden. Wird z.B. ein Timer-ISR aufgerufen (und dadurch automatisch das Timer-ISR-Flag gelöscht), dann kann noch während der Abarbeitung dieses ISR das lokale ISR-Flag wieder gesetzt werden. Die Abarbeitung erfolgt dann (fast*) direkt nach dem Beenden der gerade laufenden ISR-Routine. * fast, weil: Zwischen 2 ISR-Aufrufen wird immer ein Befehl des Hauptprogramms ausgeführt: "When the AVR exits from an interrupt, it will always return to the main program and execute one more instruction before any pending interrupt is served." Viele Grüße, Stefan
Jörg W. schrieb: > A. K. schrieb: >> Das muss sich nicht decken, beispielsweise wenn die Entscheidung über >> den Vektor erst unmittelbar davor getroffen wird, was mehr oder weniger >> deutlich nach dem Stack-Push vom PC geschehen kann. > > Um das zu wissen, müsste man wohl in den Verilog-Code reingucken. ;-) Oder man probiert es einfach mal aus. Oliver
Oliver S. schrieb: > Martin S. schrieb: >> Der Atmega2560 hat sogar 12 Interruptvektoren. > > Hat der nicht, der hat 57. > Es macht ja nichts, daß du bisher noch nie mit den AtMegas zu tun > hattest, aber so deutlich musst du es ja nicht zeigen. Die Dinger sind > nunmal in vielem sehr viel einfacher gestrickt als „richtige“ > Mikrocontroller. > > Oliver Dann weißt du mehr als Atmel. Die 12 stehen da nämlich in den Release Notes.
Martin S. schrieb: > Dann weißt du mehr als Atmel. Die 12 stehen da nämlich in den Release > Notes. rtfm http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf S. 101 - 102
Martin S. schrieb: > Die 12 stehen da nämlich in den Release Notes. Welche Release Notes? Aber da du es nicht glaubst, hier mal ein Screenshot des Datenblatts. Ich musste es bis zur Unleserlichkeit skalieren, damit alle auf den Bildschirm passen …
Das Einzige, was an dieser "Priorisierung" (das kam sicher aus der Atmel-Marketingabteilung) wichtig ist: Wenn ISR eine Weile disabled waren (durch cli oder einen anderen ISR) und sich in dieser Zeit mehrere ISR-Flags angesammelt haben, dann werden diese in der Reihe ihrer Priorität abgearbeitet. Das bedeutet für niedrigpriore ISRs, dass ihre Latenzzeit worstcase (*) die Abarbeitungszeit aller höher prioren ISRs beträgt. (*) Wenn sich einer dieser ISRs innerhalb dieser Zeit wiederholen kann, wird es sogar noch schlimmer. Viele Grüße, Stefan
Hallo, zusammengefasst. Wenn ein Interrupt eingetroffen und ausgeführt wird, kann noch ein zweiter gleichen Typs erkannt werden, der dann abgearbeitet wird wenn der erste des Typs fertig ist. Tritt während der Abarbeitung des erstens noch ein dritter ein, geht dieser und alle weiteren verloren, bis der erste fertig ist. Anders ausgedrückt, an der Tür klingelt es (Interrupt) du gehst gucken und quatscht mit der Person. Du bearbeitest den ersten Interrupt. Während dessen klingelt es nochmal. Du registrierst das eine zweite Person etwas von dir will und merkst dir das. Wenn du das erste Gespräche beendest gehste zur nächsten Person. Während du jedoch mit der ersten Person noch redest, ignorierst du konseqent alles weitere klingeln nach der zweiten Person.
Checker schrieb: > Während du jedoch mit der > ersten Person noch redest, ignorierst du konseqent alles weitere > klingeln nach der zweiten Person. Nicht ignorieren. Ignorieren würde bedeuten, dass du es mitbekommst. Das ist aber das Problem, du bekommst erst gar nicht mit dass es da noch eine 3, 4, 5 usw. Person gibt, die mit dir Quatschen will. Ansonsten aber ein gutes Analogon.
Checker schrieb: > Tritt während der > Abarbeitung des erstens noch ein dritter ein, geht dieser und alle > weiteren verloren, bis der erste fertig ist. Nö, der zuletzt eingetroffene - welcher von der Priorität her an der Reihe ist - wird abgearbeitet. Das Flag kennt keine Reihenfolge-Nr. - der letzte (aktuelle) "Interrupt-Zustand" wird bearbeitet. Stell Dir einen PIN-Change-Interrupt vor - wenn es in der Zwischenzeit 3 oder 5 oder 15 davon gab kann nur der letzte (halbwegs) korrekt verarbeitet werden - oder? Das "halbwegs" ist auch der Grund dafür, warum man "niederwertige" Interrupts mit Vorsicht geniessen sollte :-) Checker schrieb: > Anders ausgedrückt, an der Tür klingelt es (Interrupt) du gehst gucken > und quatscht mit der Person. Du bearbeitest den ersten Interrupt. > Während dessen klingelt es nochmal. Du registrierst das eine zweite > Person etwas von dir will und merkst dir das. Wenn du das erste > Gespräche beendest gehste zur nächsten Person. Während du jedoch mit der > ersten Person noch redest, ignorierst du konseqent alles weitere > klingeln nach der zweiten Person. Nö, wie vor - der letzte Klingler ist der nächste - alle dazwischen sind Schall und Rauch :-)
Dieter F. schrieb: > Nö, wie vor - der letzte Klingler ist der nächste - alle dazwischen sind > Schall und Rauch :-) Nö, im Prinzip hat Checker schon recht: der zweite Klingler hat das Flag gesetzt, daher weiß man, dass da noch jemand an der Tür steht und wartet. Die nachfolgenden Klingler setzten nur das schon gesetzte Flag erneut, die bekommt man also nicht mit.
M. K. schrieb: > Die nachfolgenden Klingler setzten nur das schon gesetzte Flag > erneut, die bekommt man also nicht mit. Da verstehst Du etwas nicht richtig. Das Flag ist und bleibt gesetzt - aber nur der letzte - aktuelle - Klingler ist sichtbar. Die Vergangenheit ist Vergangenheit ... und bleibt es auch. Oder glaubst Du im Ernst, ein PIN-Change wird gespeichert? Dann verrate mir bitte wo :-)
Dieter F. schrieb: > Da verstehst Du etwas nicht richtig. Das Flag ist und bleibt gesetzt - Ja, aber wer hat denn das Flag gesetzt? Der letzte Klingler oder der Zweite? Das ist doch der Knackpunkt ;) Dieter F. schrieb: > Oder glaubst Du im Ernst, ein PIN-Change wird gespeichert? Dann verrate > mir bitte wo :-) Ja, im Pin Change Interupt Flag Register.
:
Bearbeitet durch User
M. K. schrieb: > Ja, aber wer hat denn das Flag gesetzt? Der letzte Klingler oder der > Zweite? Du kannst sie nicht mehr unterscheiden. Du weißt, dass nur noch mindestens ein Zweiter geklingelt hat. Wie viele es wirklich waren, verrät dir niemand mehr.
M. K. schrieb: > Ja, aber wer hat denn das Flag gesetzt? Der letzte Klingler oder der > Zweite? Das ist doch der Knackpunkt ;) Der ERSTE Klingler nach dem aktuellen Interrupt (sorry für das Geschrei). Ein Flag kann man nur einmal setzen (es sei denn, es wurde zwischenzeitig gelöscht - aber nicht in diesem Beispiel). M. K. schrieb: > Ja, im Pin Change Interupt Flag Register. Im "Pin Change Interupt Flag Register" wird das Flag gespeichert - sonst REIN GAR NICHTS (nochmals sorry für das Geschrei). Der Zustand des entsprechenden Ports hat sich in der Zwischenzeit 0 ... n mal geändert. Nur der letzte Zustand in der Interrupt-Verarbeitung kann ausgewertet werden. Vergangene Zustände des Ports sind nicht mehr verfügbar.
Jörg W. schrieb: > Du kannst sie nicht mehr unterscheiden. Du weißt, dass nur noch > mindestens ein Zweiter geklingelt hat. Wie viele es wirklich > waren, verrät dir niemand mehr. Dieter F. schrieb: > Der ERSTE Klingler nach dem aktuellen Interrupt (sorry für das > Geschrei). Ein Flag kann man nur einmal setzen. Eben, das mein ich doch. Ich glaub wir reden aneinander vorbei. Es wird gespeichert, dass mindestens noch einer geklingelt hat, es könnte aber auch tausende gewesen sein, das wissen wir nicht. Dieter F. schrieb: > Nur der letzte Zustand in der Interrupt-Verarbeitung > kann ausgewertet werden. Und genau das ist der Knackpunk. Es ist nicht der letzte Zustand sondern der erste, der die Interrupt-Verarbeitung anschubst. Der letzte Zustand ist nur der, der (möglicherweise) noch verfügbar ist, angeschubst hat die Verarbeitung aber der erste Zustand. Beim obigen Beispiel heißt das also: Nicht der letzte Klingler bewegt dich dazu noch mal zur Tür zu gehen sondern der zweite Klingler. Ob der dann noch da ist wenn du zur Tür gehst ist eine völlig andere Frage.
:
Bearbeitet durch User
M. K. schrieb: > Und genau das ist der Knackpunk. Es ist nicht der letzte Zustand sondern > der erste, der die Interrupt-Verarbeitung anschubst. Der letzte Zustand > ist nur der, der (möglicherweise) noch verfügbar ist, angeschubst hat > die Verarbeitung aber der erste Zustand. Nö, das ist Quackes. Nur weil der letzte das Flag nicht setzen kann heisst nicht, dass er es nicht angestossen hat. Im Falle "Flag" hat der Letzte Recht. (Punkt) Nur dessen "Grund" für das Flag kann bearbeitet werden - oder? M. K. schrieb: > Nicht der letzte Klingler bewegt > dich dazu noch mal zur Tür zu gehen sondern der zweite Klingler. Nö - den hört der Interrupt gar nicht. Der ist taub für Klingeln. Erst wenn er beendet ist, werden Klingeln wieder gehört - z. B. die 5. oder 15. Klingel.
Dieter F. schrieb: > Nö - den hört der Interrupt gar nicht. Der ist taub für Klingeln. Erst > wenn er beendet ist, werden Klingeln wieder gehört - z. B. die 5. oder > 15. Klingel. FSoweit ich weiß wird das Flag gelöscht wenn die ISR angesprungen wird.
Beitrag #5182142 wurde von einem Moderator gelöscht.
M. K. schrieb: > FSoweit ich weiß wird das Flag gelöscht wenn die ISR angesprungen wird Ja und wieder gesetzt, wenn ein erneutes Interrupt-Ereignis eintritt. Wie Du auch schon geschieben hast. M. K. schrieb: > der zweite Klingler hat das Flag > gesetzt
Beitrag #5182150 wurde von einem Moderator gelöscht.
Jörg W. schrieb: >> Ich glaub wir reden aneinander vorbei. > Nö, wir meinen alle dasselbe. :) Aber bei der Diskussion kann man feststellen, dass es gar nicht so einfach ist, ein wasserdichtes Manual zu schreiben. Viele Grüße, Stefan
M. K. schrieb: > Dieter F. schrieb: >> Da verstehst Du etwas nicht richtig. Das Flag ist und bleibt gesetzt - > > Ja, aber wer hat denn das Flag gesetzt? Der letzte Klingler oder der > Zweite? Das ist doch der Knackpunkt ;) Beide! Bei jedem Eintreten der Interrupt-Bedingung wird das Flag gesetzt, unabhängig davon, ob es vorher schon gesetzt war oder nicht. Dieter F. schrieb: > M. K. schrieb: >> Ja, aber wer hat denn das Flag gesetzt? Der letzte Klingler oder der >> Zweite? Das ist doch der Knackpunkt ;) > > Der ERSTE Klingler nach dem aktuellen Interrupt (sorry für das > Geschrei). Ein Flag kann man nur einmal setzen Und beim zweiten Versuch explodiert es? Da kann ich beliebig oft eine 1 rein schreiben. Sie wird den Zustand nicht mehr ändern, aber reingeschrieben hab ich sie trotzdem. Dieter F. schrieb: > M. K. schrieb: >> Die nachfolgenden Klingler setzten nur das schon gesetzte Flag >> erneut, die bekommt man also nicht mit. > > Da verstehst Du etwas nicht richtig. Das Flag ist und bleibt gesetzt - > aber nur der letzte - aktuelle - Klingler ist sichtbar. Die > Vergangenheit ist Vergangenheit ... und bleibt es auch. Hier vermischst du zwei Sachen: Die Auslösung des Interrupts und den Status der Hardware. Abgesehen davon: Wenn zwei Pins, die am selben Pin-Change-Interrupt hängen, ihren Zustand wechseln, sieht man danach selbstverständlich von beiden den neuen Zustand und nicht nur vom letzten der beiden.
Rolf M. schrieb: > Beide! Bei jedem Eintreten der Interrupt-Bedingung wird das Flag > gesetzt, unabhängig davon, ob es vorher schon gesetzt war oder nicht. Quackes - ein Bit kann nur einmal gesetzt werden. Rolf M. schrieb: > Und beim zweiten Versuch explodiert es? Da kann ich beliebig oft eine 1 > rein schreiben. Sie wird den Zustand nicht mehr ändern, aber > reingeschrieben hab ich sie trotzdem. Nö, was da ist (als Bit) kann nicht mit gleichem Wert "überschrieben" werden. Rolf M. schrieb: > sieht man danach > selbstverständlich von beiden den neuen Zustand und nicht nur vom > letzten der beiden. Bezogen auf M. K. stimmt das. Warum beantworte ich so etwas eigentlich - dazu sind doch Moderatoren da oder? :-)
Dieter F. schrieb: > Rolf M. schrieb: >> Beide! Bei jedem Eintreten der Interrupt-Bedingung wird das Flag >> gesetzt, unabhängig davon, ob es vorher schon gesetzt war oder nicht. > > Quackes - ein Bit kann nur einmal gesetzt werden. Ich kann in ein Register reinschreiben, was ich will, auch das, was schon drin steht. > Rolf M. schrieb: >> Und beim zweiten Versuch explodiert es? Da kann ich beliebig oft eine 1 >> rein schreiben. Sie wird den Zustand nicht mehr ändern, aber >> reingeschrieben hab ich sie trotzdem. > > Nö, was da ist (als Bit) kann nicht mit gleichem Wert "überschrieben" > werden. Also hat der Prozessor eine Schaltung eingebaut, die vor dem Setzen des Registers prüft, ob es schon gesetzt ist und dann den Schreibvorgang unterdrückt? Oder wie genau wird verhindert, dass der gleiche Wert nochmal reingeschrieben wird?
Rolf M. schrieb: > Oder wie genau wird verhindert, dass der gleiche Wert > nochmal reingeschrieben wird? Gar nicht - aber was ist die Auswirkung? Ändert sich irgendetwas?
Dieter F. schrieb: > Gar nicht - aber was ist die Auswirkung? Die Auswirkung ist, dass deine Aussage Dieter F. schrieb: > ein Bit kann nur einmal gesetzt werden. falsch ist. Ob sich irgend etwas ändert ist wieder eine ganz andere Frage.
M. K. schrieb: > Die Auswirkung ist, dass deine Aussage > > Dieter F. schrieb: >> ein Bit kann nur einmal gesetzt werden. > > falsch ist. Ob sich irgend etwas ändert ist wieder eine ganz andere > Frage. Setze das Bit bitte 2 mal - und berichte die Auswirkung. Insbesondere die Aussage, dass das Bit 2 oder n-mal gesetzt wurde ( mit Nachweis der Änderungen auf Bit-Ebene)
Dieter F. schrieb: > Setze das Bit bitte 2 mal - und berichte die Auswirkung Du verstehst es einfach nicht. Ursache und Wirkung sind zwei verschiedene Dinge. Macht hier keinen Sinn weiter zu diskutieren.
M. K. schrieb: > Du verstehst es einfach nicht. Ursache und Wirkung sind zwei > verschiedene Dinge. Macht hier keinen Sinn weiter zu diskutieren. Nö - Du verstehst es nicht - ein Bit kann man nur setzen oder löschen - ob mehrfach oder einfach spielt keine Rolle.
Dieter F. schrieb: > ein Bit kann man nur setzen oder löschen - > ob mehrfach oder einfach spielt keine Rolle. Und genau das verstehst du nicht. Du mischst Aktion (= Bit setzen) mit Reaktion (= Bit ist gesetzt). Wenn du eine Tasse voll Wasser hast (= Bit ist gesetzt) kann du in diese Tasse eine weitere Tasse Wasser kippen (= Bit setzen). Die Tasse ist dann immer noch voller Wasser (= Bit ist immer noch gesetzt), das ändert aber nichts daran, dass du eine weitere Tasse Wasser in die Tasse geschüttet hast (= das Bit ein weiteres Mal gesetzt hast). Du hast natürlich völlig recht, dass das keine Rolle spielt ob man ein Bit noch mal setzt wenn es schon gesetzt ist, es ändert aber nichts an der Aktion dass man es noch mal gesetzt hat.
:
Bearbeitet durch User
M. K. schrieb: > Und genau das verstehst du nicht. M. K. schrieb: > Du hast natürlich völlig recht, dass das keine Rolle spielt ob man ein > Bit noch mal setzt wenn es schon gesetzt ist, es ändert aber nichts an > der Aktion dass man es noch mal gesetzt hat. Ja.
Dieter F. schrieb: > Nö - Du verstehst es nicht - ein Bit kann man nur setzen oder löschen - > ob mehrfach oder einfach spielt keine Rolle. Richtig. Genau das hatte ich ja geschrieben: Rolf M. schrieb: > Da kann ich beliebig oft eine 1 rein schreiben. Sie wird den Zustand nicht > mehr ändern, aber reingeschrieben hab ich sie trotzdem. Oben hattest du aber noch behauptet, das Schreiben wäre gar nicht mehr möglich, wenn schon eine 1 drin steht.
A. K. schrieb: > Er hat nur asynchrone Interrupts, aber keine synchronen. Falsch. Man kann jeden externen (also Pin-bezogenen) AVR-Interrupt zu dem machen, was einen "synchronen Interrupt" ausmacht (das ist schlicht einer, den die Software selber induziert, nicht externe Ereignisse). In den Datenblättern wird auch jeweils ausdrücklich auf diese Möglichkeit hingewiesen. Darüber hinaus kann man natürlich auch durch entsprechende Programmierung der jeweiligen Peripherie-Baugruppen auch fast jeden anderen Interrupt der AVR8-Peripherie zu einem "synchronen" Interrupt machen, nur die zu erwartenden Latenzen variieren natürlich etwas... Das Minimum für die Latenz sind halt zwei Takte, (alle externen Interrupts und Timer bei entsprechender Konfiguration). Das entspricht exakt der Minimal-Latenz für die Auslösung von AVR8-Interrupts überhaupt.
c-hater schrieb: > Falsch. Postings, die so brachial anfangen, stehen meist auf sehr wackeligen Beinen. Du gibst lediglich Beispiele dafür, wie man die Peripherie "missbrauchen" kann, um das gleiche Verhalten wie bei synchronen Interrupts zu erzielen. Das bedeutet nicht, dass der AVR synchrone Interrupts eingebaut hat. Ich kann auch ein Auto fliegen lassen, indem ich es mit einem großen Katapult werfe. Das macht daraus aber kein Flugzeug.
Habe ich etwas geraucht - oder habt ihr etwas geraucht? Wir schreiben von Flags und plötzlich tauchen synchrone und asyncrone Interrupts auf. Interessant! @C-Hater: Kannst Du bitte auf der Flag-Ebene bleiben? Danke! Falls das nicht geht erkläre bitte mal den Unterschied zwischen synchronen und ansychronen Interrupts auf Basis des besprochenen ATMega328 in diesem Thread. Ich bin gespannt und warte auf Deine Ausführungen.
Beitrag #5182292 wurde von einem Moderator gelöscht.
Johannes schrieb: > Hallo, > werden Interrupts eigentlich gespeichert, solange diese noch nicht > ausgeführt worden sind? (In meinem Fall für einen Atmega328) Ja, es wird ein Interrupt-spezifisches Bit gesetzt (RXC0 wenn ein Mega368 ein Byte via UART0 empfangen hat) und in der Regel gibt es ein EnableInt-Bit, mit dem man die Ausführung der zugehörigen ISR freigeben kann. Falls dann die CPU "Zeit hat", sprich bei gesetztem I-Flag nach jeder Ausführung eines Befehls, wird der PC auf den Stack ge-pushed und der ISR-Vector angesprungen. Ein AVR löscht dabei auch das I-Flag bis spätesten zum RETI, das sich vom RET nur durch setzen des I-Flags unterscheidet. Gibt es nun ein anderes Interrupt-Bit das auf 1 sitzt und freigegeben ist, dann wird diese ISR ausgeführt. Viele Interrupt-Quellen setzen ihr Intflag automatisch zurück, z.B. UART-Receive, wenn das Data-Register gelesen wird und sind ab dann bereit das nächste "Interrupt-Ereignis" zu speichern manche müssen aber auch explizit zurückgesetzt werden, andernfalls gibt es "Dauer-ISR". Ein "Löw-Level"-Mode von INTn verhält sich auch so. Solange Löw anliegt, wird die ISR immer wieder neu gestartet. Will man das umgehen, muß man das zugehörende Enable-Bit löschen. > Wie verhält es sich, wenn ich eine Interruptroutine für eine Steigende > und fallende Flanke erstelle (z.B. von einem Button (Prellen > vernachlässige ich jetzt mal)) > > Wenn ich diesen Button sehr schnell drücke, sodass ein Interrupt > ausgelöst wird, obwohl die erste Interrupt-Routine noch nicht fertig > ist, wird diese danach wider ausgelöst? Wie viele Interrupts können > gespeichert werden? Bei einem Button wird der μC wohl immer mitkommen, es gibt aber bei der AVR-UART den Fall, das das Senderegister Daten aufnehmen kann (UDRE User Data Register Empty). Diese werden, falls das Schiftregister auch frei ist sofort dorthin weiter geleitet und damit ist, noch bevor die ISR enden kann UDRE wieder gesetzt. Wird dies von der ISR nicht behandelt, kommt es nach RETI und der Ausführung eines Befehls der Main-Loop gleich zum nächsten Int, da ja das auslösende Bit wieder sitzt. Es werden also schnell folgende "Ereignisse" gespeichert, sobald der 1-Bit-Zähler, der sich diese merkt und nur bis 1 zählen kann, wieder "Platz hat", sprich gelöscht wurde. > Was passiert wenn ich ein Delay habe (nehmen wir mal an 5 Sekunden) und > ich drücke während des Delays den Button ein paar mal. Wird der > Interrupt auch ausgelöst? Nein, denn erst wenn das eine "Ereignis" in der ISR "quittiert wurde, kann das nächste gespeichert werden. > Es ist nicht so, dass ich diese Probleme habe (vor allem nicht mit dem > Delay), es interessiert mich nur, wie soetwas vom uC gehändelt Das les ich gern, denn zunehmend scheint das Verstehen wollen durch schnelles C&P ersetzt zu werden. Thumbs up!
c-hater schrieb: > A. K. schrieb: > >> Er hat nur asynchrone Interrupts, aber keine synchronen. > > Falsch. > > Man kann jeden externen (also Pin-bezogenen) AVR-Interrupt zu dem > machen, was einen "synchronen Interrupt" ausmacht (das ist schlicht > einer, den die Software selber induziert, nicht externe Ereignisse). In > den Datenblättern wird auch jeweils ausdrücklich auf diese Möglichkeit > hingewiesen. So vorhanden (z.B. bei vielen Megas) verwendet man da besser den SPM-Int. Der ist nur dann nicht aktiv, wenn ein Flash-Write ausgeführt wird, und kann sonst durch setzen seines Enable-Bits ausgelöst werden (synchron, "Software-Int"). Da braucht man kein Pin für!
Carl D. schrieb: > und > kann sonst durch setzen seines Enable-Bits ausgelöst werden (synchron, > "Software-Int"). Da braucht man kein Pin für! Mal 'ne blöde Frage: Warum tut man sich das an, mit den 'Software Interrupts'? Kann man nicht die benötigte Funktion einfach direkt aufrufen (call)? Ich sehe da irgendwie keinen Vorteil... Christoph
Christoph schrieb: > Carl D. schrieb: >> und >> kann sonst durch setzen seines Enable-Bits ausgelöst werden (synchron, >> "Software-Int"). Da braucht man kein Pin für! > Mal 'ne blöde Frage: Warum tut man sich das an, mit den 'Software > Interrupts'? Kann man nicht die benötigte Funktion einfach direkt > aufrufen (call)? > Ich sehe da irgendwie keinen Vorteil... > > Christoph Wenn die CPU verschiedene "Run-Modes" kennt, dann ist ein Soft-Int das einzige Mittel um vom "Anwendungs-Modus" in den "System-Modus" zu wechseln. Das ist bei einem AVR kein Thema (weil nicht vorhanden), aber spätestens bei ARM Cortex-M gibt es 2 verschiedene Run-Modes und der Befehl SVC (SuperVisor Call), der einen Software-Interrupt auslöst.
Dieter F. schrieb: > Falls das nicht geht erkläre bitte mal den Unterschied zwischen > synchronen und ansychronen Interrupts auf Basis des besprochenen > ATMega328 in diesem Thread. Ich bin gespannt und warte auf Deine > Ausführungen. Brauchst Du nicht mehr - habe es im Datenblatt nachgelesen.
Hallo, nochmal zurück zum Thema. Bin auch der Meinung das ein gesetztes Bit ein gesetztes Bit bleibt. Mit neu setzen ist da nichts. Es wird zwischendurch nicht gelöscht wenn zu viele Interrupts hintereinander zu schnell eintreffen. Fakt ist doch es gehen Interrupts verloren, wenn die ISR länger benötigt wie das zeitliche eintreffen aufeinander folgender Interrupts. Der zweite Interrupt wird zwar erkannt, kann aber noch nicht abgearbeitet werden. Selbst hierbei geht schon eine Information verloren, falls wichtig, wann der Interrupt eingetroffen ist. Aber er wurde erkannt und wird irgendwann abgearbeitet. Alle weiteren, solange die ISR noch beschäftigt ist, wiederholen nur die Interruptanforderung. Ignorieren war vielleicht etwas falsch ausgedrückt. Wenn irgendwann keine Interrupts mehr eintreffen, wird aus Sicht des µC der vemeintlich 2. Interrupt abgearbeitet. Real ist es aber der letzte. Der zeitliche Bezug ging verloren. Nochmal mit der Türklingel. Es klingelt (Interrupt), man geht zur Tür, notiert sich die Zeit und quatscht mit der Person. Die ISR wird abgearbeitet. Während dessen klingelt es wieder. Man merkt sich das noch jemand von einem was möchte. Während man immer noch mit der ersten Person (ISR) quatscht, klingelt es immer wieder einmal. Man merkt sich dennoch nur das irgendwer noch von einem etwas möchte. Nicht wieviele. Irgendwann ist alles bequatscht und die ISR beendet. Man geht wieder zur Tür um den nächsten ISR abzuarbeiten und notiert sich erneut die Zeit. Ab hier gibts eine Diskrepanz. Man weiß nicht ob die neue Person der zweite oder zehnte war der geklingelt hat. Das heißt auch die notierte Zeit kann ich nur dem erneuten ISR Aufruf zuordnen. Nicht der Reihenfolge der zu viel eingetroffenen Interruptanforderungen.
Checker schrieb: > Man weiß nicht ob die neue Person der > zweite oder zehnte war der geklingelt hat. Ja, man sieht nur die Person, die gerade (nachdem der Besucher gegangen ist / die ISR abgearbeitet ist) geklingelt hat - nicht die welche es vorher versucht haben.
Checker schrieb: > Nochmal mit der Türklingel. Es klingelt (Interrupt), man geht zur Tür, > notiert sich die Zeit und quatscht mit der Person. Die ISR wird > abgearbeitet. Während dessen klingelt es wieder. Man merkt sich das noch > jemand von einem was möchte. Während man immer noch mit der ersten > Person (ISR) quatscht, klingelt es immer wieder einmal. Falsch, es klingelt durchgehend. Deshalb hinkt auch die Türklingel, die man ja immer wieder los läßt. Das Interruptflag bleibt aber durchgehend "an". > Man merkt sich > dennoch nur das irgendwer noch von einem etwas möchte. Nicht wieviele. Wäre auch mit dem Interruptflag gar nicht möglich.
Checker schrieb: > Hallo, > > nochmal zurück zum Thema. > Bin auch der Meinung das ein gesetztes Bit ein gesetztes Bit bleibt. Mit > neu setzen ist da nichts. Es wird zwischendurch nicht gelöscht wenn zu > viele Interrupts hintereinander zu schnell eintreffen. Richtig. Deshalb ist es auch müßig, darüber zu diskutieren, ob jetzt in dem Bit das erste oder das zweite Ereignis gespeichert ist. Es ist eine 1 drin, fertig. > Alle weiteren, solange die ISR noch beschäftigt ist, wiederholen nur die > Interruptanforderung. Ignorieren war vielleicht etwas falsch ausgedrückt. > Wenn irgendwann keine Interrupts mehr eintreffen, wird aus Sicht des µC > der vemeintlich 2. Interrupt abgearbeitet. Real ist es aber der letzte. Nein. Für den Prozessor gibt's keinen 2. oder letzten Interrupt. Er hat eine solche Information überhaupt nicht. Er hat nur ein gesetztes Interrupt-Flag. > Ab hier gibts eine Diskrepanz. Man weiß nicht ob die neue Person der > zweite oder zehnte war der geklingelt hat. Im Gegensatz zu deinem Beispiel weiß man bei der ISR nicht einmal, ob einer, zwei oder zehn geklingelt haben. Du weißt nur: Es wurde inzwischen geklingelt. Du weißt weder, wie oft, noch wann. > Das heißt auch die notierte Zeit kann ich nur dem erneuten ISR Aufruf > zuordnen. Nicht der Reihenfolge der zu viel eingetroffenen > Interruptanforderungen. Weder Reihenfolge, noch Anzahl. Stell dir die Analogie so vor: Du hast einen Anrufbeantworter, aber der Speicher ist voll (oder kein Band eingelegt, wenn er schon etwas älter ist). Wenn jemand anruft, geht nur die LED an, die anzeigt, dass Anrufe eingegangen sind. Wenn du nach hause kommst, hast du nur diese LED, die dir sagt, dass jemand angerufen hat. Du weißt weder wer das war, noch wann, noch wieviele oder in welcher Reihenfolge. Du hast nur das eine Bit, das sagt: "jemand hat angerufen".
:
Bearbeitet durch User
Hallo, ich bin überzeugt wir meinen alle das Gleiche, nur die Wortwahl ist bei dem einen oder anderen etwas anders und daraus das Verständnis der Worte beim lesenden anders. Ob nun Klingel oder AB, völlig egal. Sinnbildlich dargestellt das gleiche Ergebnis. Der Klingelknopf soll den von außen einwirkenden neuen Interrupt darstellen. Das gesetzte Bit für weitere ISR Anforderungen ist im Kopf des dort wohnenden. Der hat eben nur ein Bit um sich das zu merken. Unser gemeinsamer Nenner bleibt ja davon unberührt, weil er richtig ist. :-) Wünsche allen noch ruhiges WE.
Dieter F. schrieb: > Ja, man sieht nur die Person, die gerade (nachdem der Besucher gegangen > ist / die ISR abgearbeitet ist) geklingelt hat - nicht die welche es > vorher versucht haben. Ich korrigiere - wenn diese Person überhaupt noch da ist - wenn nicht wieß man nur, dass es geklingelt hat. Wie Rolf schreibt ...
Loipe schrieb: > Falsch, es klingelt durchgehend. Deshalb hinkt auch die Türklingel, die > man ja immer wieder los läßt. Das Interruptflag bleibt aber durchgehend > "an". Es gibt Interrupt-Systeme, bei denen es vorkommen kann, dass zu dem Zeitpunkt, zu dem eigentlich der Handler bestimmt werden soll, nicht mehr bekannt ist, worum es eigentlich ging. Das ist dann ein wenig so, wie bei der Türklingel. Du wachst auf, gehst zur Tür, machst auf - und keiner ist da.
Checker schrieb: > Bin auch der Meinung das ein gesetztes Bit ein gesetztes Bit bleibt. Mit > neu setzen ist da nichts. Es wird zwischendurch nicht gelöscht wenn zu > viele Interrupts hintereinander zu schnell eintreffen. Genauso ist das. Die IRQ-Flags der AVR8 können nur maximal ein (weiteres) Auftreten des jeweiligen Interrupts puffern. > Fakt ist doch es gehen Interrupts verloren, wenn die ISR länger benötigt > wie das zeitliche eintreffen aufeinander folgender Interrupts. Es ist sogar noch viel schlimmer: Jede Interruptsperre hat diese Wirkung, nicht nur die des eigenen Interrupts, also insbesondere auch jede andere ISR im System (zumindest so lange sie exklusiv ausgeführt wird). > Der > zweite Interrupt wird zwar erkannt, kann aber noch nicht abgearbeitet > werden. Noch nicht... > Selbst hierbei geht schon eine Information verloren Ja. Das gilt allerdings für die "erste" Instanz dieses Interrupts schon (fast) im gleichen Maße. Die Unsicherheit über den Zeitpunkt der Abarbeitung bezogen auf den Zeitpunkt der Auslösung nennt man Interruptlatenz. Diese setzt sich aus zwei Teilen zusammen, der konstanten Latenz (die logischerweise für beide Instanzen vollkommen gleich ist) und der variablen Latenz, die für die Folgeinstanz nur um genau so viel größer ist, wie der exklusiv ausgeführte Teil der konkreten ISR dauert. Die restlichen Teile der variable Latenz (i.d.R. das wirklich Schlimme!) sind für beide Instanzen aber gleich, nämlich die SUMME der (exklusiven) Laufzeiten aller ISRs mit höherer Priorität zuzüglich der längsten exklusiven Laufzeit sonstiger Interruptsperren, also der exklusive Teil aller ISRs geringerer Priorität und von cli/sei-Blöcken in main(). > Alle weiteren, solange die ISR noch > beschäftigt ist, wiederholen nur die Interruptanforderung. Ignorieren > war vielleicht etwas falsch ausgedrückt. Naja, semantisch setzt der Begriff "ignorieren" eine gewisse Absicht voraus, insofern ist er wohl wirklich nicht korrekt. Aber er stellt zumindest die Wirkung zutreffend dar. > Wenn irgendwann keine > Interrupts mehr eintreffen, wird aus Sicht des µC der vemeintlich 2. > Interrupt abgearbeitet. Real ist es aber der letzte. Ganz genau das ist die logische Konsequenz, wie dein Türklingel-Beispiel recht gut darstellt.
A. K. schrieb: > Es gibt Interrupt-Systeme, bei denen es vorkommen kann, dass zu dem > Zeitpunkt, zu dem eigentlich der Handler bestimmt werden soll, nicht > mehr bekannt ist, worum es eigentlich ging. Jepp. Der klassische PC(AT) mit seinen kaskadierten Interruptcontrollern z.B. ist ein sehr schönes Beispiel dafür, wie man ein Interruptsystem besser nicht aufbauen sollte. Broken by design... Aber auch der Amiga z.B. hatte ein sehr ähnliches Problem. Fiel dort nur nicht so auf, weil man die Hardware schon sehr ungewöhnlich nutzen musste, um den Effekt hervorzulocken. Wie auch immer: wenn die Hardware schon Scheisse ist, wird Software hilflos, selbst wenn der Programmierer komplett durchblickt. Da bleibt nur Schadensbegrenzung. Die allseits beliebten "hardware behaviour work arounds", die ja immer so viel billiger sind, als einfach mal die Hardware nachzubessern...
c-hater schrieb: > Die Unsicherheit über den Zeitpunkt der Abarbeitung bezogen auf den > Zeitpunkt der Auslösung nennt man Interruptlatenz. > > Diese setzt sich aus zwei Teilen zusammen, der konstanten Latenz (die > logischerweise für beide Instanzen vollkommen gleich ist) und der > variablen Latenz, die für die Folgeinstanz nur um genau so viel größer > ist, wie der exklusiv ausgeführte Teil der konkreten ISR dauert. > > Die restlichen Teile der variable Latenz (i.d.R. das wirklich Schlimme!) > sind für beide Instanzen aber gleich, nämlich die SUMME der > (exklusiven) Laufzeiten aller ISRs mit höherer Priorität zuzüglich der > längsten exklusiven Laufzeit sonstiger Interruptsperren, also der > exklusive Teil aller ISRs geringerer Priorität und von cli/sei-Blöcken > in main(). Ja - Latenz. Heisst für mich, der Zustand - welcher den Interrupt ausgelöst hat - kann noch bestehen, muss aber nicht. Das ist bitter und muss bei der Abarbeitung eines Interrupts berücksichtigt werden. Alternativ muss man entsprechende Maßnahmen (welche auch immer) treffen.
c-hater schrieb: > Jepp. Der klassische PC(AT) mit seinen kaskadierten Interruptcontrollern > z.B. ist ein sehr schönes Beispiel dafür, wie man ein Interruptsystem > besser nicht aufbauen sollte. Yep. Da lugt noch der alte 8080 um die Ecke. Näher dran am Forum: Viele klassischen ARMs, besonders die mit Interrupt Controller PrimeCells von ARM drin, wie dem VIC. Etwa die LPC2000 Familie. Der VIC speichert die Anforderung nicht selbst sondern reicht sie kombinatorisch durch. Wenn z.B. eine UART eine bereits ausgegebene Interrupt-Anforderung wieder zurück nimmt, etwa bei einem FIFO Timeout Interrupt, der von eintrudelndem Byte abgebrochen wird, dann gibts einen "spurious interrupt", von dem keiner weiss, wo er herkommt. > Broken by design... Für das Interrupt-System der klassischen ARM Architektur kann man das generell sagen, jedenfalls bei verschachtelten Interrupts. > Aber auch der Amiga z.B. hatte ein sehr ähnliches Problem. Fiel dort nur > nicht so auf, weil man die Hardware schon sehr ungewöhnlich nutzen > musste, um den Effekt hervorzulocken. Bei 68000 wars der vektorierte Modus. Wenn der Urheber des Interrupts beim Vektor-Zyklus selbst nicht mehr wusste, welchen er dem Prozessor liefern soll. Autovektoriert wars sauber. Bei den LPC2000 musste man das unbedingt im Auge haben, sonst gabs gelegentliche nicht leicht verfolgbare Schmutzeffekte. > Wie auch immer: wenn die Hardware schon Scheisse ist, wird Software > hilflos In jedem grösseren Mikrocontroller gibts ziemlich viel Scheisse. Meist kann man damit leben, wenn man sie kennt.
:
Bearbeitet durch User
A. K. schrieb: >> Broken by design... > > Für das Interrupt-System der klassischen ARM Architektur kann man das > generell sagen, jedenfalls bei verschachtelten Interrupts. Heisst das "wer ARM nimmt ist arm dran" :-) ?
Dieter F. schrieb: > Heisst das "wer ARM nimmt ist arm dran" :-) ? Nö. Denn andernfalls ist Arm ab. ;-)
Typischer Weise gibt es je Interruptquelle ein Pending-Flag, d.h. es kann nur ein Ereignis je Quelle gespeichert werden. Das Pending-Flag bewirkt dann das Ausführen des Handlers, sobald der Interrupt erlaubt ist. Je nach Quelle wird das Pending-Flag beim Eintritt in den Handler automatisch gelöscht oder muß per Software gelöscht werden. Als Fallgrube beim AVR muß zum Löschen von Pending-Flags eine 1 in das Bit geschrieben werden (auf 0 setzen hat keinen Effekt). Das Pending-Flag kann auch abgefragt (gepollt) werden, es muß also zur Behandlung der Quelle nicht unbedingt ein Interrupt ausgeführt werden. Wird ein Interrupt längere Zeit gesperrt, muß bei erneuter Freigabe vorher das Pending-Flag gelöscht werden, sonst kriegt man einen Interrupt auf veraltete Ereignisse. Aufpassen muß man bei asynchronen Timern, da das Flag durch die Synchronisationsregister verzögert gelöscht wird. Z.B. beim T1 des ATtiny261 muß man 2 NOPs dazwischen einfügen.
Beitrag #5184032 wurde vom Autor gelöscht.
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.