Hallo,
bisher habe ich beim ATmega unterbrechbare INT-Routinen vermieden.
Ich denke momentan aber über ein Projekt nach, wo sich das wohl nicht vermeiden lassen wird. Dazu hab ich mir mal den Artikel
durchgelesen.
Im Prinzip ist das schon alles klar. In Assembler auf nem 8031 hab ich früher solche Sachen auch schon gemacht.
Mir ist da jetzt nur eine Aussage in dem Artikel aufgefallen, die mir nicht ganz einleuchtet:
------snip ------------------------------------------------------- #include
ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */ { /* Interrupt-Code */ }
....Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das Global Enable Interrupt Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden ? auch XXX-Interrupts.
Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen durch Rekursion...
Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau: ...
ISR (XXX) { // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen
// Erlaube alle Interrupts (ausser XXX) sei();
//... Code ...
// IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos // aktivieren zu koennen cli();
} Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.
---------------- snip --------------------------------------------------
Wieso sollte sich der xxx-IRQ selbst unterbrechen können?
Ich dachte, das könnte nur ein höher priorisierter IRQ? Es müsste doch ausreichen, das IRQ-Flag am Ende der ISR-Routine zu löschen. Dann gehen zwar diese zusätzlichen IRQ-Anforderungen verloren, aber bei meiner aktuellen Anwendung wäre das sogar erwünscht.
Gruß
Stefan