Rückkehr von Interrupts an einem anderen Ort als dem, wo der Interrupt auftritt. (PIC16F877A)

Gibt es eine Möglichkeit, von Interrupts an einem anderen Ort zurückzukehren als dem, an dem der Interrupt in Microchip PIC16F877A aufgetreten ist?

Ich habe ein Problem, bei dem mein Code an einem bestimmten Punkt neu gestartet werden muss, immer wenn ein externer Interrupt auftritt und die ISR gerade beendet wird.

Ich denke an Inline-Assembler-Anweisungen in meinem C-Code, um die Adresse zu erhalten, die ich zurückgeben möchte, und um die Spitze des Stapels auf diese Adresse zu ändern, aber ich denke, der PIC16F877A unterstützt das nicht.

Warum nicht die nächste Instruktion nach der ISR dorthin schicken, wo es hingehen soll?
Weil ich nicht weiß, was die nächste Anweisung nach der ISR ist. Es hängt davon ab, wo sich der Programmzähler zum Zeitpunkt des Interrupts befand.
Leider gibt Ihnen die PIC16-Serie keinen Zugriff auf die Stapelregister, sodass Sie die Rücksendeadresse nicht manipulieren können. Wenn Sie diese Funktionalität wirklich benötigen, müssen Sie auf einen PIC18 upgraden.
Was genau versuchst du zu tun?
Sie können auf diesem PIC nicht tun, wonach Sie fragen, aber das klingt nach einem Implementierungsdetail, das Sie sich vorgestellt haben, anstatt nach Ihrem wahren Problem. Es klingt auch nach klobiger Softwarearchitektur, wenn Sie dies tun möchten.

Antworten (2)

Sie haben Recht, PICs vor PIC18 gaben keine Möglichkeit, die Spitze des Stapels zu ändern.

Sie stellen eine der klassischen Fragen, die mich veranlasst hat, PICs zu meiden, und insbesondere alles vor PIC18 wie die sprichwörtliche Pest. Wikipedia-PIC-Stack

Es ist eine völlig normale Sache, vorausgesetzt, Sie verstehen, was Sie tun, und es ist nicht unlogisch. Es ist ein Kernmechanismus für Multitasking- oder Multiprozess-Betriebssysteme.

Der normale Grund für so etwas ist ein Kontextwechsel des Betriebssystems (OS). Dies würde Software in die Lage versetzen, die Illusion vieler gleichzeitiger Prozesse zu erzeugen. Wenn ein Interrupt bedient wurde, möchte das Betriebssystem möglicherweise nicht zum unterbrochenen Prozess zurückkehren, sondern muss möglicherweise einen anderen Code ausführen. Ein Teil des Mechanismus besteht darin, den Stapelzeiger auf den Stapel eines anderen Prozesses zu ändern und dann die Rückkehr vom Interrupt auszuführen.

Siehe AN818 Manipulating the Stack of the PIC18 Microcontroller für Informationen zum Ändern der Rücksendeadresse. Beachten Sie, dass es sich um ein PIC18-Dokument handelt.

Leider AFAICT, dass PIC dazu nicht in der Lage ist.

Eine minderwertige alternative Technik besteht darin, Ihren Hauptregelkreis eine Variable überprüfen zu lassen, um festzustellen, wann sie aussteigen muss, und diesen anderen Code auszuführen.

Gibt es eine Möglichkeit, einen RESET zu erzwingen?

Hallo Gbulmer! Ich habe versucht, einen Weg zu finden, die Spitze des Stapels genau zu ändern, um die von Ihnen erwähnte minderwertige Alternative zu vermeiden. Aber wenn es keine Möglichkeit gibt, den Stack zu manipulieren, habe ich keine Wahl.
@stdio.h - Ich sympathisiere sehr. Es ist eine vollkommen vernünftige Sache, dies tun zu wollen. Vor vielen Jahren schrieb ein Kumpel von mir so etwas wie das Kern-Task-Switching für ein Echtzeit-Betriebssystem in C++, mit nur etwa 4 Zeilen Assembler, um den Stack-Zeiger zu manipulieren und diesen Stack-Swap durchzuführen. Es war nur eine Bibliothek, die in einem gewöhnlichen Prozess lief. Ich nehme an, es gibt keine Möglichkeit, die MCU zu aktualisieren?
Es ist eine Bachelorarbeit. Ich denke, mein Lehrer wird mir sagen, dass es besser ist, einen minderwertigen Code zu schreiben, als die MCU in realen Situationen zu aktualisieren. Aber ich neige wirklich dazu, die MCU zu aktualisieren, weil ich es hasse, Flags in meinem gesamten Code zu überprüfen. Es sieht nach einer schnellen Lösung aus.

Nein, was Sie verlangen, ist sowohl unmöglich als auch unlogisch.

Es wäre, als würde man auf einer Autobahn die Spur wechseln und dann wieder auf die erste Spur wechseln, aber 25 Meilen entfernt sein wollen, wenn man in die andere Richtung fährt. Es wird einfach nicht passieren, es sei denn, Sie ändern die Gesetze der Physik oder erschaffen ein Wurmloch, und glauben Sie mir, Sie wollen das nicht tun.

Ein Interrupt ist genau das, wonach es sich anhört - es unterbricht den normalen Ablauf des Programms, um einige Operationen auszuführen, dann wird der normale Ablauf des Programms fortgesetzt. Der Interrupt hat keine direkte Kontrolle über diesen Programmablauf - er kann lediglich Variablen ändern, die Ihr Hauptprogramm untersuchen könnte, um festzustellen, ob ein Neustart erforderlich ist.

Eine andere Analogie wäre, dass Sie an Ihrem Schreibtisch arbeiten und einen Brief schreiben. Das Telefon klingelt und unterbricht Sie. Du beantwortest es. Wenn Sie den Hörer auflegen, sitzen Sie immer noch mit Ihrem Brief vor sich an Ihrem Schreibtisch. Wenn Sie den Hörer auflegen, können Sie sich nicht auf die Toilette teleportieren.

Zur weiteren Klärung liefert eine schnelle Durchsicht des Datenblatts alle Beweise, die Sie benötigen, um zu wissen, dass es unmöglich ist:

Die PIC16F87XA-Familie verfügt über einen 8-Level tiefen x 13-Bit breiten Hardware-Stack. Der Stapelraum ist weder Teil des Programm- noch des Datenraums und der Stapelzeiger ist nicht lesbar oder beschreibbar. Der PC wird auf den Stapel gepusht, wenn ein CALL-Befehl ausgeführt wird oder ein Interrupt eine Verzweigung verursacht. Der Stack wird im Falle einer RETURN-, RETLW- oder einer RETFIE-Befehlsausführung POP'ed. PCLATH wird von einer PUSH- oder POP-Operation nicht beeinflusst.