Hallo,
In diesem Fall wird der externe Interrupt Pech haben, und wir garnicht wahrgenommen.
Das ist auch der Grund, warum Interrupts so kurz wie möglich gehalten werden sollen.
Gruß Sebastian
Hallo zusammen,
nehmen wir an, ich befinde mich in der Überlauf-Interrupt-Routine eines Timers. Während dieser Zeit kommt ein externer Interrupt rein. Was passiert? Wird die Timer-Routine fertiggeführt, oder hat der neue Interrupt vorrang, sodass dieser ausgeführt wird und dann wieder zum Timer gegangen wird?
Herzlichen Gruss
Mario
Hallo,
In diesem Fall wird der externe Interrupt Pech haben, und wir garnicht wahrgenommen.
Das ist auch der Grund, warum Interrupts so kurz wie möglich gehalten werden sollen.
Gruß Sebastian
Oh, geht aber rassig hier... Danke!
So was nennt man Timing
Halt, nicht unbedingt...In diesem Fall wird der externe Interrupt Pech haben, und wir garnicht wahrgenommen.
Wenn in der laufenden INT-Routine die Interrupts
wieder freigeschaltet werden (SEI),dann werden
auch weitere Interupts ausgelöst.
Vorsicht bei Level-getriggerten Interupts, die müssen
vorher extra disabled werden, sonst kommen die immer wieder,
da läuft dann blitzschnell der Stack über...
Die Priorität gleichzeitig auftretender Interupts ist beim AVR entsprechend
der Reihenfolge der INT-Vectoren im Programmspeicher.
Gruß Jan
Im Prinzip schon, aber es ist wohl kein guter Programmierstil sowas z tunWenn in der laufenden INT-Routine die Interrupts
wieder freigeschaltet werden (SEI),dann werden
auch weitere Interupts ausgelöst.
Nö, ist nicht so.Zitat von izaseba
Interrupt-Behandlung in AVR geschieht so:
- Treten mehrere IRQ gleichzeitig auf, dann wird die IRQ mit der höchsten Priorität behandelt. Je kleiner die Interrupt-Nummer, desto höher ist die Priorität. Ersichtlich im target-spezifischen avr/io.h, bei Mega8 zB avr/iom8.h oder im Manual.
- Wird eine ISR beendet, dann kommt die höchstpriore IRQ zum Zuge, die noch nicht bearbeitet wurde. Während der ersten ISR kann zusätzlich ein neuer IRQ aufgetaucht sein. Vor Verzweigen in die ISR wird aber mindesten 1 Befehl des normalen Programms abgearbeitet.
- Bei Eintritt in eine ISR werden Interrupts disabled, indem das I-Flag im SREG zurückgesetzt wird. Will man erkursive Interrupts haben, dann kann man das I-Flag setzen. Das geht zB mit sei. Oder man implementiert die ISR nicht als SIGNAL(n), sondern als INTERRUPT(n), falls man avr-gcc verwendet. Bei rekursiven IRQs muss man sich überlegen, daß das auch geht: hat man noch genug RAM um den Kontext zu sichern etc., ist eine ISR kurz genug? Denn wenn sie zu lange dauert, kann sein, daß in ihr wieder der gleicht IRQ kommt. Dann hat man ein Problem.
- In gewissem Rahmen kann man die Prioritätsebene seiner IRQs mit dem I-Flag beherrschen, ist zwar nicht so komfortabel wie in großen µC, aber es reicht eigentlich immer. INTERRUPT setzt das I-Flag direkt zu Anfang der ISR, so daß die Interrupt-Latenzzeit nur minimal steigt.
- Tritt ein IRQ auf, wird ein entsprechendes Flag gesetzt (Ausnahme unten). Nach Beenden der ISR wird es automatisch vom AVR rückgesetzt, so daß man sich nicht drum kümmern muss. Es gibt aber auch Ausnahmen, wie zB beim TWI. Da muss man das entsprechende Flag selber rücksetzen, weil darüber auch der Clock-Stretch an SCL gemacht wird.
- Der einzige IRQ die verloren gehen könnte, ist ein level-getriggerter externer IRQ, weil der kein Flag hat. Aber den wird man im normalen Betrieb eh nicht verwenden, sondern nur im sleep-Mode, um den AVR aufzuwecken. Im normalen Betrieb nimmt man die flankengetriggerten externen IRQs.
- Es bleibt immer noch der Poll-Betrieb, also indem man selber auf das Flag schaut, das durch ein Ereignis gesetzt wird (Timer-Overflow, InputCapture, TWI, UART, ...) Dann muss man das Flag selber löschen, damit es wieder gesetzt werden kann. Flags beim AVR werden idR dadurch gelöscht, daß man eine 1 hinschreibt.
- Ob Interrupt-Betrieb besser ist oder Poll-Betrieb, kann man nicht allgemein sagen. Das hängt von vielen Faktoren ab: Latenzzeit, Implementierungsaufwand, Codegröße, Priorisierung, Platz aufm Stack, etc...
IRQ = Interrupt ReQuest
ISR = Interrupt Service Routine
Disclaimer: none. Sue me.
Lesezeichen