Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Um bestimmte Hardwarefunktionen eines SPB-verbundenen Peripheriegeräts zu verwenden, muss ein Client des SPB-Controllers (d. h. ein Peripherietreiber) möglicherweise eine Abfolge von Datenübertragungen an und vom Gerät als Atombusbetrieb durchführen. Die Übertragungssequenz ist atomar, da kein anderer Client Daten an oder von einem Gerät im Bus übertragen kann, bis die Sequenz abgeschlossen ist.
Die typische Möglichkeit für einen Client, eine Übertragungssequenz als Atombusvorgang auszuführen, besteht darin, eine IOCTL_SPB_EXECUTE_SEQUENCE Anforderung an das Zielgerät zu senden. In dieser Anforderung gibt der Client die Sequenz als Liste einfacher Lese- und Schreibübertragungen an. Die Liste kann beliebig lang sein. Die Lese- und Schreibvorgänge werden in der Reihenfolge ausgeführt, in der sie aufgelistet werden, und jeder Lese- oder Schreibzugriff kann eine beliebige Anzahl von Bytes übertragen. Die meisten SPB-Controller unterstützen IOCTL_SPB_EXECUTE_SEQUENCE Anforderungen.
SPB-Controllersperren
Eine weniger häufige Möglichkeit zum Ausführen einer Atomübertragungssequenz besteht darin, eine SPB-Controllersperre zu verwenden. Ein Client sendet eine IOCTL_SPB_LOCK_CONTROLLER Anforderung zum Abrufen der Sperre und eine IOCTL_SPB_UNLOCK_CONTROLLER Anforderung zum Freigeben der Sperre. Wenn ein Client die Controllersperre hält, werden alle Sequenzen einfacher Lese- und Schreibanforderungen (IRP_MJ_READ und IRP_MJ_WRITE), die der Client an das Gerät sendet, als atomare Vorgänge auf dem Bus ausgeführt.
Die meisten mit SPB verbundenen Peripheriegeräte erfordern keine Controllersperren, und die meisten SPB-Controllertreiber implementieren keine Unterstützung für diese Sperren. Einige Clients müssen jedoch möglicherweise Controllersperren verwenden, um auf Geräte zuzugreifen, die ungewöhnliche Features aufweisen.
Beispielsweise könnte ein Gerät Gerätefunktionen implementieren, auf die nur über Lese-Modifizieren-Schreib-Operationen zugegriffen werden kann, die auf dem Bus atomar sind. Um einen solchen Vorgang auszuführen, sendet der Client die folgenden vier E/A-Anforderungen (in der angezeigten Reihenfolge):
- IOCTL_SPB_LOCK_CONTROLLER – Erwerben Sie die Controllersperre.
- IRP_MJ_READ – Lesen eines Datenblocks von einem Zielgerät.
- IRP_MJ_WRITE – Schreiben Sie die geänderten Daten zurück auf das Gerät.
- IOCTL_SPB_UNLOCK_CONTROLLER – Lassen Sie die Controllersperre los.
Nach dem Lesevorgang in der vorherigen Liste interpretiert der Client die Daten, die vom Gerät gelesen wurden, und ändert die Daten, bevor sie wieder auf das Gerät geschrieben werden.
Wenige SPB-verbundene Geräte verfügen jedoch über Funktionen, die Controllersperren erfordern. Für die meisten Geräte, die einen Atombusbetrieb erfordern, sind IOCTL_SPB_EXECUTE_SEQUENCE Anforderungen ausreichend.
Verwechseln Sie SPB-Controllersperren nicht mit SPB-Verbindungssperren. In dem atypischen Fall, in dem zwei Clients zugriff auf dasselbe SPB-verbundene Peripheriegerät teilen, kann jeder Client eine Verbindungssperre verwenden, um vorübergehend exklusiven Zugriff auf das Gerät zu erhalten. Weitere Informationen finden Sie unter SPB-Verbindungssperren.
Hardwarebussignale
Um eine IOCTL_SPB_EXECUTE_SEQUENCE Anforderung zu verarbeiten, konfiguriert ein SPB-Controllertreiber die Controllerhardware, um während der Übertragungssequenz die entsprechenden Signale auf dem Bus zu generieren. Peripheriegeräte, die an den Bus angeschlossen sind, können von diesen Signalen abhängig sein, um zu erkennen, wann ein Atombusbetrieb ausgeführt wird. Der Satz von Hardwaresignalen, die ein SPB-Controller zum Ausführen einer Übertragungssequenz als Atombusbetrieb verwendet, hängt vom Bustyp ab.
Für einen I2C-Bus startet der Controller eine Sequenz, indem ein Startbit auf dem Bus übertragen wird und eine Sequenz durch Übertragung eines Stoppbits beendet wird. Zwischen Start- und Stoppbits erfolgt die Abfolge der Datenübertragungen an und vom Gerät als einzelner Atombusbetrieb. Mit Ausnahme der endgültigen Übertragung in der Sequenz folgt jede Übertragung einem I2C-Neustartvorgang (ein wiederholtes Startbit, dem kein Stoppbit vorangestellt ist).
Bei einem SPI-Bus startet der Controller eine Sequenz, indem die Chipauswahllinie zum Zielgerät aktiviert wird. Die Sequenz wird beendet, indem die Chipauswahllinie zurückgesetzt wird. Indem die Chipauswahllinie während einer Folge von Datenübertragungen über den Bus kontinuierlich aktiviert wird, werden die Übertragungen als einzelne atomare Busoperation durchgeführt.
Ein Beispiel für ein I2C-Gerät
Ein typisches Peripheriegerät auf einem I2C-Bus kann mehrere interne Gerätefunktionen implementieren. Um auf einige dieser Funktionen zuzugreifen, verwendet ein Client möglicherweise IOCTL_SPB_EXECUTE_SEQUENCE Anforderungen.
Ein I2C-Peripheriegerät kann z. B. die folgenden beiden internen Register enthalten:
- Ein Funktionsadressenregister , auf das der Client die interne Adresse der Gerätefunktion schreibt, auf die zugegriffen werden soll.
- Ein Datenregister , über das der Client Daten ausliest oder in die angegebene Funktionsadresse schreibt.
Das I2C-Peripheriegerät in diesem Beispiel interpretiert das nach einem Startbit auf das Gerät geschriebene erste Byte als eine Funktionsadresse, die in das Funktionsadressregister geladen wird. Alle zusätzlichen Bytes, die vor dem Ende der Sequenz an oder vom Gerät übertragen werden (wie durch das Stoppbit angegeben), werden vom Gerät als Daten behandelt, die über das Datenregister übertragen werden.
Zum Ausführen eines Schreibvorgangs sendet der Client eine Schreibanforderung (IRP_MJ_WRITE), in der das erste Byte im Schreibpuffer die Funktionsadresse ist, und die verbleibenden Bytes im Puffer sind Daten, die in die Funktionsadresse geschrieben werden sollen.
Das Lesen vom Gerät ist komplizierter. Gehen Sie davon aus, dass das I2C-Gerät in diesem Beispiel ein Feature "schnelles Lesen" unterstützt, das das Funktionsadressenregister automatisch auf den Standardwert 0 zurücksetzt, wenn ein Stoppbit auf dem Bus erkannt wird. Mit diesem Feature kann der Client die Daten aus der Funktionsadresse 0 lesen, ohne zuerst in das Funktionsadressregister schreiben zu müssen. Dieses Feature kann die Geschwindigkeit der Gerätelesevorgänge verbessern, insbesondere, wenn die meisten Lesevorgänge von der Funktionsadresse 0 stammen und relativ kurz sind.
Um jedoch einen Datenblock aus einer Nicht-Null-Funktionsadresse zu lesen, muss der Client dennoch ein Byte in das Funktionsadressenregister schreiben, bevor der Datenblock aus dem Datenregister gelesen wird. Der Client muss diese Schreib- und Leseübertragungen als Atombusvorgang durchführen, um zu verhindern, dass der Buscontroller nach dem Schreiben in das Funktionsadressenregister und vor dem Lesen aus dem Datenregister ein Stoppbit übertragen kann. Sonst bewirkt das Stoppbit, dass die Daten von der Funktionsadresse 0 statt von der nicht-null Funktionsadresse gelesen werden.
Die folgende Liste beschreibt die Reihe von E/A-Anforderungen, die ein Client an das I2C-Gerät sendet, in diesem Beispiel, um einen Lese-Modifizieren-Schreiben-Vorgang für Daten auszuführen, die sich an einer nicht-null Funktionsadresse auf dem Gerät befinden.
- IOCTL_SPB_EXECUTE_SEQUENCE – Durchführen einer E/A-Übertragungssequenz zum Lesen von Daten vom Gerät. Die erste Übertragung in dieser Sequenz ist ein Byteschreibvorgang in das Funktionsadressenregister. Die zweite Übertragung in der Sequenz ist ein Lesevorgang einiger Bytes aus der ausgewählten Funktionsadresse. Diese beiden Übertragungen werden atomar auf dem Bus durchgeführt.
- IRP_MJ_WRITE – Schreiben von Daten auf das Gerät. Das erste Byte im Schreibpuffer für diese Anforderung ist der Wert, der in das Funktionsadressregister geschrieben werden soll. Die verbleibenden Bytes im Puffer sind Daten, die in die ausgewählte Funktionsadresse geschrieben werden sollen.
Andere Muster von Anforderungen können stattdessen verwendet werden, um diesen Lese-/Schreibvorgang auszuführen. Beispielsweise kann die IRP_MJ_WRITE Anforderung in Schritt 2 durch eine IOCTL_SPB_EXECUTE_SEQUENCE Anforderung ersetzt werden, die zwei Datenübertragungen angibt, die beide Schreibvorgänge sind. Die erste Übertragung in der Sequenz lädt ein Byte in das Funktionsadressenregister. Die zweite Übertragung schreibt die Datenbytes in die ausgewählte Funktionsadresse. Diese Anforderung erfordert im Gegensatz zur IRP_MJ_WRITE Anforderung in Schritt 2 nicht, dass der Client das Funktionsadressenbyte und Datenbytes im gleichen Schreibpuffer kombiniert.
Zum Ausführen eines Lese-Änderungs-Schreibvorgangs auf Funktionsadresse 0 auf diesem Gerät kann die IOCTL_SPB_EXECUTE_SEQUENCE-Anforderung in Schritt 1 der vorherigen Liste durch eine einfache Leseanforderung (IRP_MJ_READ) ersetzt werden.