Software-Interrupt vs. Funktion

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.

Ich denke, der Hauptzweck der Verwendung von Interrupts besteht darin, dass Sie andere wichtige Aufgaben erledigen können, während Sie darauf warten, dass etwas anderes passiert, und wenn die Timings nicht immer konstant sind. Ich denke auch, dass es in den meisten Fällen etwas schneller ist als Polling.
@MrPhooky Das sind Hardware-Interrupts, von denen Sie sprechen. Das OP spricht von Software-Interrupts.

Antworten (3)

Der Hauptunterschied zwischen einer Funktion und einem Software-Interrupt ist der sogenannte Kontext .

  • Eine Funktion wird im Kontext Ihres Hauptprogramms ausgeführt.
  • Ein Interrupt läuft im Kontext des Interrupt-Handlers.

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.

Außerdem können Interrupts den Fortschritt eines Programms willkürlich anhalten, damit das System etwas anderes tun kann (z. B. Hardware-Interrupts). Ihre Programme müssen dies nicht berücksichtigen, da der Zustand der Funktion aus Sicht Ihres Programms seit dem Zeitpunkt des Interrupts unverändert ist. Auf älteren Systemen simulierten TSR-Programme (Terminate/Stay Resident) auf diese Weise Multitasking, indem sie den Timer/Clock-Interrupt abschalteten. Auch ohne IOPL-Werte war es beispielsweise von Vorteil, die Systemuhr auf dem neuesten Stand zu halten.
Beachten Sie vielleicht auch, dass diese "Software-Interrupts" auch als "synchrone Interrupts" bezeichnet werden, da der Anwendungscode genau weiß, wann und warum ein solcher Interrupt auftritt, im Gegensatz zu "asynchronen Interrupts", die aus Sicht der Bewerbung, grundsätzlich jederzeit unaufgefordert erfolgen.
@HannoBinder: Ich denke, das OP spricht davon, Interrupt-Anforderungen an den Cortex-M3-Vectored-Interrupt-Controller zu senden. Wenn der Code für einen Interrupt mit hoher Priorität einen Interrupt mit niedrigerer Priorität sendet, wird die Anforderung bis zu einem späteren Zeitpunkt verschoben, wenn alle Interrupts mit höherer Priorität beendet sind.

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.

Ein weiteres häufiges Muster kann sein, einen 100-kHz-Interrupt zu haben, um zeitkritische Dinge zu verarbeiten, und auch einen 1-kHz-Timer-Tick zu benötigen, aber nicht zwei separate Timer verfügbar zu haben. Es braucht nicht viel Overhead für eine 100-kHz-Interrupt-Routine, um zu sagen, dass 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.
Auf ähnliche Weise habe ich Software-Interrupts in einfachen Systemen (ohne vollständiges RTOS) als Pseudo-Scheduler verwendet, bei dem die Hardwareanforderungen von den ISRs behandelt werden, aber Callback-Funktionen und andere langwierige Aufgaben, die als Reaktion auf Änderungen in Der Hardwarezustand wird an den Software-Interrupt delegiert.
Sie haben im Grunde eine Variation von "unterer Hälfte" beschrieben. Haben Sie einen Hinweis darauf, dass dies auch als "Software-Interrupt" bezeichnet wird? Es hat eine ganz andere Bedeutung als Majenkos Antwort, und die Frage ist mit ARM gekennzeichnet - die Architektur hat tatsächlich die SWI-Anweisung (Software Interrupt).
@domen Ich bin mir nicht sicher, welche Art von Referenz Sie benötigen. Es wird als "Software-Interrupt" bezeichnet, weil das verwendet wird, um es zu erreichen. Im Zusammenhang mit ARM hat das OP speziell auf den STM32 verwiesen und einen Link zum RM0008-Referenzhandbuch bereitgestellt. Dies ist kein ARM-Core-Referenzhandbuch. Der einzige in RM0008 behandelte "Software-Interrupt" ist das EXTI_SWIER (Software-Interrupt-Ereignisregister), das verwendet werden kann, um Software-Interrupts zu erzeugen, unabhängig davon, ob die tatsächlichen Hardware-Pins für Interrupts verwendet werden oder nicht. Ich habe die SWI (SWC)-Anweisung nicht persönlich verwendet.
Vielen Dank! Es könnte gut sein, einige dieser Informationen in die Antwort aufzunehmen, um klarzustellen, um welchen "Software-Interrupt" es sich handelt.

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.

Und in vielen Fällen, in denen das Betriebssystem Soft-Interrupts verwendet, sind sie in Funktionen verpackt, um das Leben einfacher zu machen.
Ich programmiere immer noch Dinge (auch ganz neue) für DOS und bin mit den int 21-Handlern sehr vertraut. Fast alles, was ich I/O-technisch benötige, wird mit dem DOS ISR gehandhabt.
Beachten Sie, dass die für Linux zitierte Seite von 1993-1996 stammt.
Ich habe den Link durch einen aktuelleren ersetzt.