Woher weiß der Controller, wann er zum ISR springen muss?

12

Ich spreche von Dingen auf der Kernebene.

Soweit ich weiß, führt der Controller-Core nur Befehle aus, die aus dem Speicher abgerufen werden (Fetch - Decode - Execute). Wie entscheidet sich der Kern / die ALU, wenn ein Interrupt eintrifft, zum ISR zu springen?

Da wir oder der Compiler keine Anweisung zum Abfragen des Interruptstatus hinzufügen - woher weiß er dann, dass ein Interrupt bedient werden muss?

Swanand
quelle

Antworten:

13

Was Sie vermissen, ist, dass der Core nicht nur Opcodes ausführt, die aus dem Speicher abgerufen werden. Es enthält eine spezifische Logik zum Implementieren von Interrupts.

Wenn die Interrupt-Erkennungshardware das Signal bestätigt, das besagt, dass es Zeit ist, einen Interrupt auszuführen, wird normalerweise ein spezieller Befehl in den Kern gestaut, der nie aus dem Speicher abgerufen wurde. In den meisten Fällen handelt es sich um eine CALL-Anweisung an die Interrupt-Vektoradresse. Hierbei wird der vorhandene Mechanismus zur Befehlsausführung verwendet, um den aktuellen PC auf dem Aufrufstapel zu speichern und in die Interrupt-Vektoradresse zu ändern. Sie befasst sich auch mit dem Verwerfen von vorabgerufenen Anweisungen und dergleichen.

Die spezielle Interrupt-Erfassungslogik muss Interrupts auch so deaktivieren, dass dieselbe Interrupt-Bedingung im nächsten Zyklus keinen weiteren Aufruf der Interrupt-Vektoradresse verursacht. Verschiedene Prozessoren haben unterschiedliche Möglichkeiten, damit umzugehen. Am einfachsten ist es, Interrupts nur fehlerfrei zu deaktivieren, sodass die Software sie am Ende der Interrupt-Serviceroutine erneut aktivieren muss. Andere Prozessoren haben eine Interrupt-Prioritätsstufe. Dieser Pegel ist erhöht, so dass nur Interrupt-Bedingungen mit höherer Priorität einen neuen Interrupt verursachen können. Die Interrupt-Priorität wird dann automatisch zusammen mit der CALL-Rücksprungadresse gespeichert und wiederhergestellt, wenn der Code vom Interrupt zurückkehrt.

Olin Lathrop
quelle
1
Oft handelt es sich nicht um eine gewöhnliche CALLAnweisung, da Interrupts auf andere Weise beendet werden (vgl. RETVs. RETI).
Glglgl
1
Kann ich mit Sicherheit davon ausgehen, dass die CPU, wenn die Interrupt-Erkennungshardware das Signal bestätigt, anstelle des Speichers die Anweisung erhält, von einer anderen Stelle zu springen? Wie bei einem Schalter vielleicht? , Diesen Befehl ausführen?
Swanand
3

In modernen Mikrocontrollern gibt es üblicherweise eine eigene Interrupt-Controller-Einheit (IC), die für die Verwaltung von Interrupts zuständig ist. Zusätzlich hat jede Peripheriekomponente einen oder mehrere Interrupt-Ausgänge, die von 0nach 1(oder umgekehrt) gehen, wenn eine Bedingung zutrifft (z. B. hat dieses Peripheriegerät einige Arbeiten abgeschlossen). Dieser Ausgang ist mit dem Interrupt-Controller verbunden. Die CoreCPU kann dem IC anweisen, diesen bestimmten Interrupt zu ignorieren (zu maskieren) oder die MCU zu benachrichtigen, wenn dies durch Auslösen bestimmter Signale geschieht, und dann entscheidet die MCU, was damit zu tun ist. Der übliche Weg ist, dass der IC der MCU mitteilt, welcher Interrupt aufgetreten ist, und zu dem entsprechenden Bearbeitungscode springt.

Eugene Sh.
quelle
2

Es gibt Hardware im Computerkern, die einen neuen Wert in den Programmzähler staut, der dem bestimmten ausgelösten Interrupt entspricht. Um sich zu merken, wohin Sie nach Beendigung der Interruptroutine zurückkehren müssen, wird der aktuelle Wert des Programmzählers in den Stapel geschrieben, bevor die Hardware die Interruptadresse in den Programmzähler schreibt. Nach Beendigung der Interruptroutine wird der ursprüngliche Wert des Programmzählers wieder aus dem Stapel entfernt.

Die Werte, die zur Unterbrechungszeit in den Programmzähler eingespeist werden sollen, werden normalerweise durch eines von zwei Schemata bestimmt. Ein Ansatz staut eine feste Adresse für jeden Interrupt-Typ in den Programmzähler, und der Computerkern startet dann die Ausführung an diesem festen Ort. Der Platz an dem festen Ort ist häufig in der Größe begrenzt, so dass es üblich ist, einen Sprungbefehl an den festen Adressen zu codieren, die zu dem tatsächlichen Unterbrechungsdienstort übergehen. Das andere Schema verwendet eine sogenannte Interrupt-Vektortabelle. Hier generiert die Hardware einen festen Adressoffset in der Vektortabelle basierend auf dem Interrupttyp. Die Hardware holt dann den Inhalt an dieser Tabellenposition heraus und verwendet diesen Wert als Adresse, um in den Programmzähler einzugreifen.

Michael Karas
quelle
2

Die Steuerung hat ein Register für den Programmzähler , das die Adresse verfolgt, an der der nächste auszuführende Befehl gespeichert ist. (Dieses Register wird auch geschrieben, wenn ein Sprung ausgeführt wird.)

Die Steuerung hat einen Interrupt-Vektor (oder manchmal mehr als einen, abhängig von der Art des Interrupts), der die Adresse ist, an der der ISR gespeichert ist. Diese Adresse ist immer gleich - es ist wie beim Reset-Vektor, bei dem das Programm startet.

(Häufig ist in diesem Vektor ein Sprungbefehl gespeichert, der zum eigentlichen auszuführenden Code springt, da der Speicherplatz im Vektor nicht ausreicht, um die gesamte Prozedur zu speichern. Wichtig ist jedoch, dass sich der ISR immer am selben Ort befindet Position.)

Wenn ein Interrupt auftritt, befindet sich eine dedizierte Hardware in der Steuerung, die den Programmzähler mit dem Interrupt-Vektor schreibt. Wenn die Steuerung dann den nächsten Befehlszyklus erreicht, ruft sie den Befehl von der Adresse ab, auf die der Programmzähler (also der Interrupt-Vektor) zeigt.

(In einem Befehlszyklus der Steuerung werden verschiedene Aufgaben ausgeführt: Es ruft den nächsten Befehl von der Adresse ab, auf die der Programmzähler zeigt. Es erhöht den Programmzähler. Es decodiert den Befehl und führt ihn aus.)


quelle