Nach ungefähr 3 Jahren Arbeit mit MCUs weiß ich immer noch nicht, was die Verwendung von Software-Interrupts ist. Ich habe mehrere Jobs mit STM32 erledigt und die Software-Interrupts nie verwendet. In der Tat ist dies eine große Frage für mich:
Warum sollten wir, wenn wir eine einfache Funktion verwenden können, um eine Aufgabe zu erledigen, einen Software-Interrupt verwenden? Was sind die Unterschiede zwischen einem Software-Interrupt und einer Funktion?
Sie können jederzeit eine Funktion aufrufen (die Sie für Ihren Job geschrieben haben). Die Verwendung eines Software-Interrupts anstelle einer einfachen Funktion sollte einige Vorteile haben. Ich bin mir nicht sicher, aber ich denke, es gibt einen Vorteil für Software-Interrupts: Sie können einem Software-Interrupt eine Priorität zuweisen, dann können Sie dem Software-Interrupt eine höhere Priorität geben, um zu vermeiden, dass der Hardware-Interrupt Ihre Aufgabe unterbricht.
Der Hauptunterschied zwischen einer Funktion und einem Software-Interrupt ist der sogenannte Kontext .
Auf einem einfachen System mag dies kein wirklicher Unterschied sein, und Software-Interrupts können einfach als bequeme Möglichkeit verwendet werden, um im ROM fest codierte Bibliotheksroutinen bereitzustellen - Sie müssen nicht die Adresse jeder Routine kennen, sondern nur den ID-Code und die Haupteingangspunkt. Dadurch wird Ihr Code portabler.
Auf komplexeren Systemen kann der Software-Interrupt jedoch in einer völlig anderen Umgebung ausgeführt werden, die als Kernel-Kontext bekannt ist . Normalerweise würde Ihre Anwendung in einem geschützten Benutzerkontext ausgeführt , der eingeschränkten Zugriff auf Ressourcen hat. Nur wenn Sie im Kernelkontext ausgeführt werden, können Sie die komplizierteren Aufgaben ausführen - einige Systeme beschränken sogar, welche Anweisungen ausgeführt werden können, sodass Sie einen Mechanismus benötigen, um Code im Kernelkontext auszulösen - und dafür wird ein Interrupt verwendet.
Softwareunterbrechungen können verwendet werden, um eine Unterbrechungsaufgabe mit einer niedrigeren Priorität zu beenden. Zeitkritischem Code wird oft eine hohe Interrupt-Priorität gegeben, um zu viel Latenz zu vermeiden. Sobald der zeitkritische Teil beendet ist, kann es zusätzliche Tasks geben, die für die Hauptschleife zu zeitkritisch sein können, aber nicht so kritisch sind, dass sie andere Interrupts mit hoher Priorität aufhalten. Dies kann durch Auslösen eines Software-Interrupts niedrigerer Priorität erreicht werden.
Angenommen, Sie haben mehrere Schrittmotoren mit jeweils eigenem Timer. Den Timer-Interrupts wird eine hohe Priorität gegeben, um Schritt-Jitter zu minimieren. Die zeitkritischste Aufgabe kann so einfach sein wie das Setzen oder Löschen eines Schrittimpulses oder das Vorrücken der Phasenausgänge. Möglicherweise sind zusätzliche Funktionen erforderlich, wie z. B. die Berechnung von Beschleunigungsrampen, Sensorverarbeitung usw. Da dies bei jedem Schritt verarbeitet werden muss, ist es möglicherweise nicht angemessen, dies von main() aus zu verarbeiten, da das Timing der Hauptschleife zu lang sein kann. Diese zusätzlichen Aufgaben können von einem Software-Interrupt mit niedrigerer Priorität verarbeitet werden, um die Latenz der anderen Stepper-Kanäle mit hoher Priorität nicht zu erhöhen.
Was ist der Unterschied zwischen einem Software-Interrupt und einer Funktion?
Eine Funktion wird sofort aufgerufen, wo immer sie aufgerufen wird, und ändert die aktuelle Interrupt-Prioritätsstufe nicht, wenn sie von einem Interrupt aufgerufen wird. Ein Software-Interrupt ist ein Interrupt-Trigger, der bewirkt, dass dieser Interrupt aufgerufen wird, wenn seine Priorität eintritt. Wenn am Ende eines Interrupts mit hoher Priorität ein Funktionsaufruf eingefügt würde, wäre die Funktion in diesem Interrupt mit hoher Priorität enthalten. Durch Auslösen des Software-Interrupts mit niedrigerer Priorität und anschließendem Zurückkehren von dem Interrupt mit hoher Priorität wird die Funktionalität mit der neuen (niedrigeren) Priorität aufgerufen.
if ((timer_count--) & 0x80000000) SET_TICK_INTERRUPT_FLAG(); else timer_count = temp-1;
der andere Interrupt dann sein Ding machen kann und bei kurzzeitig deaktivierten Interrupts 100 zu timer_count hinzufügt; Selbst wenn die 1-kHz-Routine 10 us für die Ausführung benötigt, wird sie die 100-kHz-Routine nicht stören.Um Majenkos Antwort etwas zu erweitern, werden Software-Interrupts verwendet, um Betriebssysteme zu implementieren, insbesondere die Systemaufrufschnittstelle. Das bedeutet, dass Anwendungen nicht mit dem Betriebssystem verknüpft werden müssen, um Funktionsaufrufe durchzuführen, und der Kontextwechsel ermöglicht es dem Betriebssystem, den Zugriff auf die Hardware einzuschränken und Dinge wie geschützten Speicher zu nutzen.
Wenn Sie kein Betriebssystem verwenden und den gesamten Code auf der MCU steuern, müssen Sie wahrscheinlich keine Software-Interrupts verwenden. (Obwohl sie, wie Tut erwähnte, andere Verwendungen haben können.)
Die Linux- und MS-DOS -Systemaufrufschnittstellen auf x86 verwenden Software-Interrupts, daher verlinke ich diese als Beispiel.
MrPhooky
brhans