11. Anlage
 
zurück
11.3.3 Unterbrechungsbearbeitung


Ein wichtiger Bestandteil der Entwicklung von eingebetteten Systemen ist der Entwurf und die Implementierung von Gerätetreibern. Das sind Untersysteme für die Steuerung des Zugriffs auf externe Geräte, die die Geräteregister behandeln und auf Unterbrechungen antworten. Ein Hardware-Gerät ist ein Objekt, das parallel zu anderen Elementen des Systems arbeitet und durch eine Unterbrechung Einfluß auf den Programmablauf nehmen kann. Durch eine Unterbrechung wird der Prozessor veranlaßt, die Ausführung zu unterbrechen, einige Handlungen als Antwort auf die Unterbrechung auszuführen und mit der normalen Ausführung fortzufahren.
Das sprachabhängige Modell für Hardware-Unterbrechungen wird zusammen mit Mechanismen für die Unterbrechungsbearbeitung festgelegt. Hardwareunterbrechungs-Modell

Eine Unterbrechung (interrupt) stellt eine Klasse von Ereignissen dar, die von der Hardware oder der Systemsoftware entdeckt werden. Das Auftreten (occurance) einer Unterbrechung kann in die Generierung (generation) und die Auslieferung (delivery) aufgeteilt werden.





Die Generierung einer Unterbrechung ist das Ereignis in der zugrundeliegenden Hardware oder dem System, das die Unterbrechung dem Programm zugänglich macht.
Die Auslieferung ist die Aktion, die Teile des Programms als Antwort auf das Auftreten der Unterbrechung anstößt.
Zwischen der Generierung und der Auslieferung ist die Unterbrechung anstehend (pending). Einige oder alle Unterbrechungen können blockiert (blocked) sein. Wenn eine Unterbrechung blockiert ist, wird die Auslieferung jedes Auftretens dieser Unterbrechung verhindert.
Bestimmte Unterbrechungen sind reserviert. Die Menge der reservierten Unterbrechungen ist implementierungsabhängig. Eine reservierte Unterbrechung ist entweder eine, für die nutzerdefinierte Unterbrechungsbehandler (interrupt handler) nicht unterstützt werden, oder eine, der bereits ein Behandler durch andere implementierungsabhängige Mittel zugeteilt ist. Programmeinheiten können mit nicht-reservierten Unterbrechungen verbunden werden. Solange eine Programmeinheit mit einer Unterbrechung verbunden ist, wird sie zugeordnet (attached) genannt.
Die Ausführung eines Unterbrechungsbehandlers (interrupt handler) wird bei Auslieferung einer Unterbrechung angestoßen. Solange ein Behandler einer Unterbrechung zugeordnet ist, wird er einmal für jedes Auftreten dieser Unterbrechung aufgerufen. Während der Behandler ausgeführt wird, ist die zugehörige Unterbrechung blockiert.
Während eine Unterbrechung blockiert ist, wird das Auftreten dieser Unterbrechungen an der Auslieferung gehindert. Ob das Auftreten anstehend bleibt oder verlorengeht, ist implementierungsabhängig.
Jede Unterbrechung hat ein Standardverfahren (default treatment), das die Systemantwort auf das Auftreten einer Unterbrechung bestimmt, falls kein nutzerdefinierter Behandler zugeordnet ist. Die Menge der möglichen Standardverfahren ist implementierungsabhängig, wie auch die Methode (wenn es eine gibt), um die Standardverfahren für Unterbrechungen zu konfigurieren.
Eine Unterbrechung wird an einen Behandler (oder das Standardverfahren) ausgeliefert, der zum Zeitpunkt der Auslieferung wirksam ist. Eine von einem Behandler weitergereichte Ausnahme, die von einer Unterbrechung angestoßen wurde, hat keine Auswirkung.
Wenn die Strategie Sperren mit Prioritätsobergrenzen (Ceiling_Locking policy) (Anlage D) wirksam ist, wird der Unterbrechungsbehandler mit der aktiven Priorität ausgeführt, die die Prioritätsobergrenze des zugeordneten geschützten Objektes ist.

Dokumentationsanforderungen

Der Übersetzerhersteller sollte die Implementierung der folgenden Punkte dokumentieren:
  1. für jede Unterbrechung, welche Unterbrechungen für die Auslieferung blockiert sind, wenn ein Behandler, der der Unterbrechung zugeordnet ist, ausgeführt wird (entweder als Ergebnis einer Unterbrechungsauslieferung oder als gewöhnlicher Aufruf einer Prozedur des entsprechenden geschützten Objektes);
  2. alle Unterbrechungen, die nicht blockiert werden können, und die Auswirkung, wenn solchen Unterbrechungen Unterbrechungsbehandler zugeordnet werden;
  3. welchen Laufzeitstapel ein Unterbrechungsbehandler verwendet, wenn dies konfigurierbar ist;
  4. jede implementierungs- oder hardwareabhängige Aktivität, die ausgeführt wird, bevor ein nutzerdefinierter Unterbrechungsbehandler die Steuerung übernimmt (z. B. das Lesen von Geräteregistern, das Erkennen von Geräten);
  5. alle Zeit- oder andere Beschränkungen, die der Ausführung von Unterbrechungsbehandlern auferlegt sind;
  6. den Zustand (blockiert/nicht blockiert) von nicht-reservierten Unterbrechungen, wenn das Programm startet; wenn einige Unterbrechungen nicht blockiert sind, welchen Mechanismus kann ein Programm verwenden, um sich selbst zu schützen, ehe es die entsprechenden Behandler anbinden kann;
  7. ob der unterbrochene Prozeß mit der Ausführung fortfahren darf, ehe der Unterbrechungsbehandler zurückkehrt;
  8. das Verfahren für das Auftreten von Unterbrechungen, solange die Unterbrechung blockiert ist, d. h. ob ein oder mehrere Vorkommen für die spätere Auslieferung gehalten werden oder ob alle verloren gehen;
  9. ob vordefinierte oder implementierungsdefinierte Ausnahmen als Ergebnis des Auftretens einer Unterbrechung auftreten, und die Abbildung zwischen den Maschinenunterbrechungen (oder Fallen (traps)) und den vordefinierten Ausnahmen;
  10. für ein Mehrprozessorsystem, die Regeln, die die Auslieferung von Unterbrechungen an einen bestimmten Prozessor festlegen.
Mechanismen für die Unterbrechungsbearbeitung

Unterbrechungen treten asynchron auf, d. h. zu Zeiten, die nicht mit den Berechnungen, die sie unterbrechen, in Beziehung stehen. Deshalb sind die Aktionen, die von einem Unterbrechungsbehandler und von dem unterbrochenen Programm ausgeführt werden, den gleichen Wettlaufbedingungen ausgesetzt, wie die Aktionen, die von mehreren Prozessen ausgeführt werden. Wettlaufbedingungen können durch die Verwendung von geschützten Objekten (siehe auch Geschützte Typen S.9/10) vermieden werden. Ein Unterbrechungsbehandler soll in Ada 95 durch eine geschützte Prozedur zur Verfügung
gestellt werden.

In Ada 83 wurden Unterbrechungseingänge mit Unterbrechungen verknüpft. Bei Ada 95 wird diese Möglichkeit als veraltet betrachtet. Sie wird wahrscheinlich aus der nächsten Version der Sprache entfernt werden.

Geschützte Prozedurenals Behandler (protected procedure handler)

Eine geschützte Prozedur ohne Parameter kann als Behandler für eine Unterbrechung installiert werden. Das bedeutet, wenn die Unterbrechung auftritt, wird die Steuerung zu der geschützten Prozedur übergehen; bei Beendigung der geschützten Prozedur, wird die normale Ausführung fortgesetzt. In Übereinstimmung mit den Regeln für geschützte Operationen, kann eine geschützte Prozedur nicht aufgerufen werden, solange eine andere Operation des gleichen geschützten Objekts bearbeitet wird. Die Unterbrechung wird während dieser Zeit blockiert.
Alle Variablen, die entweder vom Unterbrechungsbehandler oder vom unterbrochenen Programm verändert werden, oder von einem verändert und vom anderen abgeprüft werden, können als Komponenten des geschützten Objektes vereinbart werden, um Wettlaufbedingungen zu vermeiden.
Das Programm verändert diese Variablen nur durch den Aufruf anderer Operationen auf dem gleichen geschützten Objekt.
I. a. ist es aus zwei Gründen für Unterbrechungsbehandler wichtig, schnell zu enden. Erstens, weil, während ein Prozessor eine Unterbrechung bearbeitet, alle andere Arbeit auf diesem Prozessor stillsteht. Wenn zu viel Zeit mit der Unterbrechungsbehandlung verbracht wird, kann es für hochpriore Prozesse schwierig sein, ihre Echtzeitgrenzwerte einzuhalten. Zweitens, während eine Unterbrechung behandelt wird, kann das Auftreten anderer Unterbrechungsarten blockiert sein. Es kann Grenzen in der Anzahl der blockierten Unterbrechungen geben, an die sich ein Prozessor erinnert, oder in der Zeitspanne, für die er sich erinnert. D. h. ein Unterbrechungsbehandler, der zu lange braucht, kann dazu führen, daß andere Unterbrechungen ignoriert werden.
Wichtiger als das wirkungsvolle Anstoßen eines Unterbrechungsbehandlers ist jedoch seine schnelle Beendigung. Normalerweise sollte ein Unterbrechungsbehandler nur aufzeichnen, daß eine Unterbrechung aufgetreten ist, und zurückkehren. Dies erlaubt einem Prozeß den Hauptteil der mit der Unterbrechung verbundenen Arbeit zu erledigen, wenn der Prozeß das nächste Mal die Möglichkeit zur Ausführung erhält. Das geschützte Objekt des Behandlers kann einen geschützten Eingang haben, der geöffnet wird, wenn das Auftreten einer Unterbrechung aufgezeichnet wird, und der Prozeß, der die Arbeit ausführen soll, kann an diesem Eingang warten bis er geöffnet wird.
Manchmal werden mit einer Unterbrechung Daten geliefert. Wenn die Gefahr besteht, daß eine zweite Unterbrechung auftritt, die die Daten überschreibt, ehe sie verarbeitet sind, dann sollten die Daten an einem sicheren Ort gespeichert werden.
Die Zuordnung zwischen einer geschützten Prozedur und einer Unterbrechung erfolgt entweder mit dem Pragma "Attach_Handler" oder dem Pragma "Interrupt_Handler":

pragma Attach_Handler ( Handler_Name, Expression );
-- Kann in der Beschreibung oder dem Rumpf eines geschützten Objektes
-- auf Bibiliotheksebene auftreten und erlaubt die statische Zuordnung
-- zwichen dem Behandler und der durch den Ausdruck bezeichneten
-- Unterbrechung; der Behandler wird zugeordnet, wenn das geschützte
-- Objekt erzeugt wird. Program_Error wird gesetzt, wenn:
-- a) die Unterbrechung reserviert ist.
-- b) die Unterbrechung bereits einen nutzerdefinierten Behandler hat.
-- c) eine vereinbarte Prioritätsobergrenze (ceiling priority) nicht
-- im Bereich von Ada.Interrupt_Priority liegt.
pragma Interrrupt_Handler ( Handler_Name );
-- Kann in der Beschreibung eines geschützten Objektes auf
-- Bibliotheksebene auftreten und erlaubt die dynamische Zuordnung
-- der parameterlosen Prozedur als Unterbrechungsbehandler für eine
-- oder mehrere Unterbrechungen. Objekte, die von einem solchen
-- geschützten Typ erzeugt werden, müssen auf Bibliotheksebene
-- vereinbart sein.

Das Paket Ada.Interrupts definiert die Benennung von Unterbrechungen und die dynamische Zuordnung von Unterbrechungsbehandlern, während das Paket Interrupt.Names die implementierungsabhängigen Namen (und konstante Werte) für Unterbrechungen enthält, die von der Implementierung unterstützt werden.

Spezifikation der Pakete "Ada.Interrupts" und "Ada.Interrupts.Namen"

Für alle in diesem Paket vereinbarten Operationen, die einen Parameter vom Typ Interrupt_ID haben, mit Ausnahme von Is_Reserved und Reference, wird eine Prüfung durchgeführt, ob die angegebene Unterbrechung nicht reserviert ist. Program_Error wird gesetzt, wenn diese Prüfung fehlschlägt. Wenn bei der Verwendung der Prozeduren Attach_Handler, Detach_Handler oder Exchange_Handler der Versuch gemacht wird, einen Behandler abzutrennen, der statisch (mit dem Pragma "Attach_Handler") zugeordnet war, wird der Behandler nicht abgetrennt, und Program_Error wird gesetzt.

In dem Verzeichnis \Beispiele\ finden sie die Implementierungen der folgenden 4 Beispiele:

  • Beispiel 1: statische und dynamische Zuordnung
  • Beispiel 2: Behandler für mehrere Unterbrechungen
  • Beispiel 3: ein einfacher Treiber für einen AD-Wandler
  • Beispiel 4: nutzerimplementierte Zeitgeber



 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.