Freigeben über


GPIO-Based Hardwareressourcen

Ab Windows 8 stehen die GPIO-Pins (Universelle E/A), die von einem GPIO-Controllertreiber gesteuert werden, anderen Treibern als vom System verwaltete Hardwareressourcen zur Verfügung. GPIO-E/A-Pins, bei denen es sich um Pins handelt, die als Dateneingaben oder Datenausgaben konfiguriert sind, sind als neuer Windows-Ressourcentyp, GPIO-E/A-Ressourcen, verfügbar. Darüber hinaus sind GPIO-Interruptpins, bei denen es sich um Pins handelt, die als Interruptanforderungseingaben konfiguriert sind, als normale Windows-Interruptressourcen verfügbar.

Eine GPIO-E/A-Ressource stellt einen Satz von mindestens einem GPIO-Pin dar, aus dem der Treiber für ein Peripheriegerät lesen oder schreiben kann. Windows blendet Details zur zugrunde liegenden Implementierung der GPIO-E/A-Pins aus, sodass Treiber für Peripheriegeräte geschrieben werden können, um abstrakte GPIO-E/A-Ressourcen zu bearbeiten. Treiber für Peripheriegeräte, die diese abstrakten Ressourcen verwenden, können plattformübergreifend funktionieren, unabhängig von der GPIO-Controllerhardware, die die Ressourcen implementiert. Eine GPIO-E/A-Ressource wird durch ein WDFIOTARGET-Handle dargestellt, das diese Ressource dem spezifischen GPIO-Controllertreiber zuordnet, der die zugrunde liegenden GPIO-Pins besitzt.

In der Regel kann ein E/A-Pin auf einem GPIO-Controller entweder für die Eingabe oder für die Ausgabe konfiguriert werden, abhängig von den Funktionen der Controllerhardware und des Geräts, das physisch mit dem Pin verbunden ist. Daher kann ein Treiber eine logische Verbindung mit dieser Pin für Schreib- oder Lesevorgänge öffnen, aber nicht für beide. Diese Einschränkung wird jedoch von der Hardware und nicht von der GPIO-Frameworkerweiterung (GpioClx) auferlegt. Wenn die Hardware das Konfigurieren eines E/A-Pins sowohl für die Eingabe als auch für die Ausgabe ermöglicht, ermöglicht GpioClx einem Treiber, eine logische Verbindung mit dem Pin für Lese- und Schreibvorgänge zu öffnen.

Bei GPIO-Pins, die als Interruptanforderungseingaben konfiguriert sind, wird die Tatsache, dass eine Interruptanforderung von einem GPIO-Pin statt von einem Interruptcontroller oder einer dedizierten Interruptanforderungszeile implementiert wird, vom Betriebssystem vollständig abstrahiert. GPIO-Interrupts werden treibern von Peripheriegeräten als abstrakte Interruptressourcen angezeigt. Die Abstraktion dieser Ressourcen wird vom GPIO-Treiberstapel und von der Hardware abstraction Layer (HAL) unterstützt. Daher können Treiber von Peripheriegeräten, die Interruptressourcen verwenden, Details zur zugrunde liegenden Implementierung dieser Ressourcen weitgehend ignorieren. Weitere Informationen finden Sie unter GPIO-Interrupts.

Das folgende Diagramm zeigt ein Beispiel für die Zuweisung von GPIO-basierten Ressourcen zu zwei Treibern für Peripheriegeräte:

Beispielzuweisung von gpio-basierten Ressourcen.

Im obigen Diagramm sind den folgenden drei GPIO-basierten Ressourcen peripheriegerätetreiber A zugewiesen:

  • Zwei Dateneingabenadeln
  • Ein Datenausgabepin
  • Ein Interrupteingabe-Pin

Die folgenden beiden GPIO-basierten Ressourcen werden dem Peripheriegerätetreiber B zugewiesen:

  • Ein Dateneingabenadel
  • Ein Interrupteingabe-Pin

Treiber A und B erhalten ihre zugewiesenen Ressourcen in ihren EvtDevicePrepareHardware-Rückruffunktionen . Wenn ein Treiber als Ressource einen Satz von einem oder mehreren GPIO-E/A-Pins empfängt, kann der Treiber eine Verbindung mit diesen Pins öffnen, um darauf zuzugreifen. Der Treiber ruft ein WDFIOTARGET-Handle ab, um die Verbindung zu identifizieren, und sendet E/A-Anforderungen an dieses Handle, um aus diesen Pins zu lesen oder in diese zu schreiben.

Codebeispiele, die zeigen, wie Sie eine Verbindung mit einer Gruppe von GPIO-E/A-Pins herstellen und E/A-Anforderungen an diese Pins senden, finden Sie in den folgenden Themen:

Verbinden eines KMDF-Treibers mit GPIO-E/A-Pins

In beiden Themen öffnet die IoRoutine Funktion im Codebeispiel je nach ReadOperation Parameterwert eine GPIO-E/A-Pinressource für Lesevorgänge oder Schreibvorgänge. Wenn die Ressource für Lesevorgänge geöffnet wird (DesiredAccess = GENERIC_READ), werden die Pins in der Ressource als Eingaben konfiguriert, und eine an die Pinressource gesendete IOCTL_GPIO_READ_PINS-Anforderung liest die Eingabewerte an diesen Pins. GpioClx lässt nicht zu, dass eine IOCTL_GPIO_WRITE_PINS-Anforderung eine Reihe von Eingabe-Pins gesendet wird, und schließt eine solche Anforderung mit einem STATUS_GPIO_OPERATION_DENIED-Fehler status ab. Wenn die Pinressource für Schreibvorgänge geöffnet wird (DesiredAccess = GENERIC_WRITE), werden die Pins in der Ressource als Ausgaben konfiguriert, und eine an die Pinressource gesendete IOCTL_GPIO_WRITE_PINS-Anforderung legt die Werte in den Ausgabelatches fest, die diese Pins antreiben. Beim Senden einer IOCTL_GPIO_READ_PINS-Anforderung an eine Reihe von Ausgabepins werden in der Regel einfach die letzten Werte gelesen, die in die Ausgabelatches geschrieben wurden.

Um eine Interruptressource zum Empfangen von Interrupts zu verwenden, muss ein Clienttreiber eine Interruptdienstroutine (ISR) mit dem Interrupt verbinden. In der Regel stellt der Treiber diese Verbindung her, indem er die WdfInterruptCreate-Methode (oder möglicherweise die IoConnectInterruptEx-Routine) aufruft . Weitere Informationen zu KMDF-Interrupts finden Sie unter Erstellen eines Interruptobjekts.

Im Gegensatz zu Plug & Play Geräten, die dynamisch mit einer Hardwareplattform verbunden und getrennt werden können, ist ein GPIO-Controllergerät dauerhaft angeschlossen. Darüber hinaus wird davon ausgegangen, dass Verbindungen zwischen GPIO-Pins und einem Peripheriegerät dauerhaft sind. (Oder, wenn das Peripheriegerät von einem Steckplatz getrennt werden kann, ist der Steckplatz für dieses Gerät reserviert.) Daher sind die verfügbaren GPIO-Ressourcen festgelegt und können in der Plattformfirmware angegeben werden. Ebenso wird davon ausgegangen, dass Treiber von Peripheriegeräten, die GPIO-Ressourcen verwenden, dedizierte Gruppen von GPIO-Ressourcen verwenden. Daher können die Ressourcenanforderungen für diese Gerätetreiber in der Plattformfirmware angegeben werden.

Wenn die Plattformfirmware einen Satz von GPIO-Pins als GPIO-E/A-Ressource festlegt, gibt die Firmware an, ob die Pins in dieser Ressource für Lese-, Schreib- oder lese- und schreibvorgänge geöffnet werden können.

Wenn ein Treiber für Peripheriegeräte mehr als eine GPIO-E/A-Ressource verwendet, muss dieser Treiber die Reihenfolge kennen, in der diese Ressourcen vom PnP-Manager aufgezählt werden. Wenn beispielsweise ein Treiber zwei GPIO-E/A-Pins verwendet, auf diese Pins jedoch unabhängig und zu unterschiedlichen Zeiten zugegriffen werden muss, sollte die Plattformfirmware jeden Pin als separate GPIO-E/A-Ressource beschreiben. Der PnP-Manager listet diese Ressourcen in der Reihenfolge auf, in der sie in der Plattformfirmware beschrieben werden, die der vom Treiber erwarteten Reihenfolge entsprechen muss.

Nachdem ein Peripheriegerätetreiber eine Verbindung mit einer GPIO-E/A-Ressource hergestellt hat, greift eine IOCTL_GPIO_READ_PINS oder IOCTL_GPIO_WRITE_PINS Anforderung, die dieser Treiber an diese Verbindung sendet, auf alle Pins in der Ressource zu. Wenn der Treiber manchmal nur auf eine Teilmenge dieser Pins zugreifen muss, muss diese Teilmenge dem Treiber als separate Ressource zugewiesen werden.

Weitere Informationen zu IOCTL_GPIO_READ_PINS Anforderungen, einschließlich der Zuordnung von Dateneingabepins zu den Bits im Anforderungsausgabepuffer, finden Sie unter IOCTL_GPIO_READ_PINS. Weitere Informationen zu IOCTL_GPIO_WRITE_PINS Anforderungen, einschließlich der Zuordnung der Bits im Anforderungseingabepuffer zu Datenausgabepins, finden Sie unter IOCTL_GPIO_WRITE_PINS.