Interrupt aktivieren, aber kein ISR

10

Ich würde gerne wissen, was passiert, wenn ein Interrupt aktiviert ist (z. B. Arbitration Lost Interrupt im CAN-Modul des LPC1778 von NXP), aber für den Interrupt wurde kein ISR definiert.

Wenn ein solcher Interrupt auftritt, weiß ich, dass das jeweilige Interrupt-Flag gesetzt wird, aber da ich keinen ISR definiert habe, wird keine Interrupt-Vektor-Offset-Adresse für die Steuerübertragung für einen solchen Interrupt gespeichert und die Steuerung wird zurückgehen zur Hauptroutine, und ich kann das Interrupt-Flag zurücksetzen, indem ich es in der Hauptroutine abfrage (das ist, was ich denke). Wird es eine Latenz geben, wenn die CPU herausfindet, dass es keinen ISR gibt, zu dem man springen kann?

Alle Lösungen, was passieren könnte, können mir wirklich helfen.

Vielen Dank.

Aktualisieren:

Ich habe CAN Interrupt auf meinem uC aktiviert, aber keinen ISR definiert. Als ich einen internen Loopback-Test durchführte, wurde der Code in eine Endlosschleife eingegeben. Hier ist der Demontagecode der Endlosschleife, die auf LPC1778 ausgeführt wird:

B       .
ENDP

Wenn Sie Interrupts verwenden, verwenden Sie den ISR.

AkshayImmanuelD
quelle
3
Sie müssen den Interrupt nicht aktivieren, um Flags in Ihrer Hauptfunktion abfragen zu können. Wenn die Bedingung auftritt, die das Flag setzt, wird dieses Flag gesetzt, unabhängig davon, ob Sie den zugehörigen Interrupt aktiviert haben oder nicht.
Brhans
Sie sagen, dass ein Interrupt-Flag "Bus Arbitration Lost" gesetzt wird, auch wenn ich den "Interrupt on Lost Bus Arbitration" nicht aktiviere (obwohl es kein Statusregister gibt, das den Verlust der Bus Arbitration mit Ausnahme des Interrupt-Statusregisters anzeigen kann)?
AkshayImmanuelD
Ja. In jeder MCU, mit der ich gearbeitet habe, werden die Interrupt-Flags immer dann gesetzt, wenn die Bedingung eintritt, die sie setzen soll. Durch Aktivieren des Interrupts wird die MCU an den Handler weitergeleitet, wenn das zugehörige Flag gesetzt ist, und durch Deaktivieren des Interrupts wird das Flag ignoriert und nicht an den Handler weitergeleitet , obwohl das Flag gesetzt ist . Das Deaktivieren / Deaktivieren des Interrupts wirkt sich nur auf das Verhalten des Sprung-zu-Interrupt-Handlers aus, nicht auf das Verhalten beim Setzen von Flags.
Brhans
Wow. Das ist etwas, was ich nicht wusste. Danke vielmals. Daher muss jeder Fahrer regelmäßig auch nach Interrupt-Statusregistern
suchen
@AkshayImmanuelD nur wenn es darauf ankommt. Wenn der Interrupt immer deaktiviert ist und sich nichts anderes um das Flag kümmert, ist es unerheblich, ob es gesetzt oder gelöscht ist.
Hobbs

Antworten:

17

Wenn kein ISR definiert ist, ist die Position für den Sprungbefehl im Interrupt-Vektor entweder null, es kann ein Sprung zu einer Ausnahmeroutine sein, es kann zum Anfang des Programms springen oder es kann eine "Rückkehr von" enthalten Interrupt "(zB RTI) Anweisung.

Hier ist eine Zerlegung einer Interrupt-Tabelle für einen ATMega 16-Prozessor, die drei nicht verwendete Interrupts zeigt, die an eine Routine weitergeleitet werden, die solche Fälle behandelt (sie kann nur in eine Endlosschleife gehen), und einen legitimen Vektor.

  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

Welche der zuvor beschriebenen Methoden zur Behandlung eines fehlenden ISR von der Architektur des Mikrocontrollers und des Compilers abhängt. Im Falle einer RTI oder einer gleichwertigen Anweisung wird sofort zur Anwendung zurückgekehrt. Wenn der Interrupt jedoch eher durch Pegel als durch Flanken ausgelöst wird, wird der Interrupt wahrscheinlich erneut ausgelöst, sodass Sie in einer Endlosschleife enden.

Ich denke, es kann von der Architektur des Chips abhängen, ob interne Interrupts (z. B. ein Zeichen, das von einem UART empfangen wird) als pegelgetriggert oder flankengetriggert betrachtet werden. Externe Interrupts können normalerweise als der eine oder andere konfiguriert werden.

Es gibt auch einen anderen Fall: Manchmal werden mehrere Interrupts zusammengefasst und verwenden denselben Vektor. Dies gilt insbesondere für ältere Prozessoren, die möglicherweise nur einige Interrupts hatten. In diesem Fall wurde die Interrupt-Ursache durch Abfragen des Status der Interrupt-Register ermittelt. Dies entspricht in etwa dem, was Sie vorschlagen.

Es ist jedoch auf jeden Fall eine schlechte Praxis, Interrupts in einem System zu haben und keinen ISR zu definieren. Tu es nicht.

tcrosley
quelle
2
.... oder es kann undefiniert sein.
Wouter van Ooijen
@WoutervanOoijen das habe ich damit gemeint, dass der Interrupt-Vektor null ist.
Tcrosley
1
Die Statusregister können nicht einige Fehler wie den oben erwähnten anzeigen. Solche Fehler haben jedoch eine Unterbrechung. Daher dachte ich daran, den Interrupt nur zu aktivieren, um den Fehler zu identifizieren und keinen ISR zu verwenden. Während ich den LPC1778 mit Keil simulierte, bekam ich keine Ausnahme, also denke ich, dass der uC den RTI wie erwähnt verwenden muss
AkshayImmanuelD
1
Beachten Sie Folgendes: Wenn Sie einen Interrupt aktivieren, Ihr Handler jedoch das Flag nicht löscht (oder es keinen Handler gibt und das Standardverhalten eine einfache Rückgabe ist), werden Sie höchstwahrscheinlich feststellen, dass Ihre MCU für immer enden wird in einer Interrupt-Schleife stecken.
Brhans
1
Die PIO-Interrupts auf dem ATSAM3X8E können flankengetriggert werden, aber die einmal eingestellte Interrupt-Bedingung wird erst gelöscht, wenn Sie das ISR (Interrupt-Statusregister) im Interrupt-Handler gelesen haben - was zu der erwähnten Schleife @brhans führt.
Simon Wright
1

Dies hängt von Ihrer MCU, Ihrem Compiler und dem Rest des Codes ab.

Meiner Erfahrung nach:

  1. AVR - Wenn Sie keinen ISR angeben, ist der Interrupt-Vektor im Flash standardmäßig 0x0000. Dies bedeutet, dass Ihre Anwendung bei jedem Interrupt in den Reset-Modus wechselt.

    Wenn Sie den Interrupt wirklich benötigen, aber den Handler nicht benötigen (z. B. den rauscharmen ADC- Abschaltmodus verwenden und den Interrupt nur zum Aufwecken der MCU verwenden), sollten Sie das Makro EMPTY_INTERRUPT verwenden

  2. NXP Kinetis (ARM) - Alle Vektoren zeigen standardmäßig auf einen Standardhandler mit einem Haltepunkt. Die CPU stoppt einfach und teilt dies Ihrem Debugger mit.

Filo
quelle