Delen via


Een USB-Type-C poortcontrollerstuurprogramma schrijven

U moet een USB-Type-C poortcontrollerstuurprogramma schrijven als uw USB-Type-C hardware de fysieke laag USB-Type-C of Power Delivery (PD) implementeert, maar niet de statusmachines implementeert die nodig zijn voor power delivery.

In Windows 10, versie 1703, is de USB-Type-C-architectuur verbeterd ter ondersteuning van hardwareontwerpen die de fysieke laag USB-Type-C of Power Delivery (PD) implementeren, maar geen bijbehorende PD-beleidsengine of protocollaag implementeren. Voor deze ontwerpen biedt Windows 10 versie 1703 een softwaregebaseerde PD-beleidsengine en apparaatbeleidsbeheerder via een nieuwe klasse-extensie genaamd "USB Connector Manager Type-C Port Controller Interface Class Extension" (UcmTcpciCx). Een clientstuurprogramma dat is geschreven door een IHV of OEM/ODM communiceert met UcmTcpciCx om informatie te verstrekken over de hardware-gebeurtenissen die nodig zijn voor de PD-beleidsengine en apparaatbeleidsbeheerder in UcmTcpciCx om te functioneren. Deze communicatie wordt mogelijk gemaakt via een set programmeerinterfaces die in dit artikel en in de naslagsectie worden beschreven.

Diagram van USB-connectorbeheer.

De UcmTcpciCx-klasse-extensie is zelf een clientstuurprogramma van UcmCx. De beleidsbeslissingen over energiecontracten, gegevensrollen, worden gemaakt in UcmCx en doorgestuurd naar UcmTcpciCx. UcmTcpciCx implementeert dit beleid en beheert de Type-C- en PD-statusmachines met behulp van de poortcontrollerinterface die wordt geleverd door uw UcmTcpciCx-clientstuurprogramma.

Samenvatting

  • Services die worden geleverd door de UcmTcpci-klasse-extensie
  • Verwacht gedrag van het clientstuurprogramma

Officiële specificaties

Belangrijke API's

USB Type-C-poortcontrollerinterface stuurprogrammaklasse-extensies referentie

UcmTcpciCx-clientstuurprogrammasjabloon

UcmTcpciCx-clientstuurprogrammasjabloon

Voordat u begint

  • Bepaal het type stuurprogramma dat u moet schrijven, afhankelijk van of uw hardware of firmware PD-statusmachine implementeert. Zie Windows-stuurprogramma's ontwikkelen voor USB-Type-C-connectors voor meer informatie.

  • Installeer Windows 10 voor desktopversies (Home, Pro, Enterprise en Education) op uw doelcomputer of Windows 10 Mobile met een USB-Type-C-connector.

  • Installeer de nieuwste Windows Driver Kit (WDK) op uw ontwikkelcomputer. De kit beschikt over de vereiste headerbestanden en bibliotheken die nodig zijn voor het schrijven van het clientstuurprogramma.

    • De stub-bibliotheek (UcmTcpciCxStub.lib). De bibliotheek vertaalt aanroepen van het clientstuurprogramma en geeft deze door aan de class-extensie.
    • Het headerbestand UcmTcpciCx.h.

    Het clientstuurprogramma wordt uitgevoerd in de kernelmodus en wordt gekoppeld aan de KMDF 1.15-bibliotheek.

    Schermopname van visual studio-configuratie voor UCM.

  • Bepaal of het clientstuurprogramma waarschuwingen ondersteunt.

  • Uw poortcontroller hoeft niet compatibel te zijn met TCPCI. De interface legt de mogelijkheden van elke Type-C poortcontroller vast. Het schrijven van een UcmTcpciCx-clientstuurprogramma voor hardware die niet tcpCI-compatibel is, omvat het toewijzen van de betekenissen van registers en opdrachten in de TCPCI-specificatie aan die van de hardware.

  • De meeste TCPCI-controllers zijn I2C-verbonden. Uw clientstuurprogramma maakt gebruik van een SPB-verbindingsresource (Serial Peripheral Bus) en een interruptlijn om te communiceren met de hardware. Het stuurprogramma maakt gebruik van de SPB Framework Extension (SpbCx) programmeerinterface. Raak vertrouwd met SpbCx door deze artikelen te lezen:

    • [Eenvoudige randapparatuurbus (SPB) Handleiding voor het ontwerpen van stuurprogramma's]
    • [Gids voor programmering van SPB-stuurprogramma's]
  • Maak uzelf vertrouwd met Windows Driver Foundation (WDF). Aanbevolen lezing: Stuurprogramma's ontwikkelen met Windows Driver Foundation, geschreven door Penny Orwick en Guy Smith.

Gedrag van de UcmTcpci-klasse-extensie

  • Als onderdeel van de uitvoering van de toestandsmachine verzendt UcmTcpciCx IOCTL-verzoeken naar de poortcontroller. In PD-berichten wordt bijvoorbeeld een IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_TRANSMIT_BUFFER aanvraag verzonden om de verzendbuffer in te stellen. Deze aanvraag (TRANSMIT_BUFFER) wordt doorgegeven aan het clientstuurprogramma. Het stuurprogramma stelt vervolgens de verzendbuffer in met de details van de classextensie.

  • UcmTcpciCx implementeert beleidsregels over energiecontracten, gegevensrollen enzovoort.

Verwacht gedrag van het clientstuurprogramma

Van het clientstuurprogramma voor UcmTcpciCx wordt verwacht dat het:

  • Wees de eigenaar van het energiebeleid. UcmTcpciCx neemt niet deel aan energiebeheer van de poortcontroller.

  • Vertaal aanvragen, ontvangen van UcmTcpciCx, naar een lees- of schrijfopdracht voor de hardware. De opdrachten moeten asynchroon zijn omdat DPM niet kan blokkeren totdat een hardwareoverdracht is voltooid.

  • Geef een frameworkwachtrijobject op dat frameworkaanvraagobjecten bevat. Voor elke aanvraag die de UcmTcpci-klasseextensie naar het clientstuurprogramma wil verzenden, voegt de extensie een aanvraagobject toe aan het wachtrijobject van het stuurprogramma. Wanneer het stuurprogramma klaar is met het verwerken van de aanvraag, wordt WdfRequestComplete aanroepen. Het is de verantwoordelijkheid van de client driver om aanvragen tijdig te voltooien.

  • Ontdek en rapporteer de mogelijkheden van de poortcontroller. Deze mogelijkheden omvatten informatie zoals de rollen waarin de poortcontroller kan werken (zoals alleen bron, alleen sink, DRP). Er zijn echter andere functies van de connector (zie opmerking over de Functiewinkel) en van het systeem als geheel, die de DPM moet kennen om het USB-Type-C- en PD-beleid correct te kunnen implementeren. De DPM moet bijvoorbeeld weten wat de bronmogelijkheden van het systeem/de connector zijn om deze aan de poortpartner te adverteren.

    Capaciteitenwinkel

    Naast de mogelijkheden voor clientstuurprogramma's is er aanvullende informatie afkomstig van een door het systeem algemene locatie aangeduid als de Capability Store. Deze systeemwijd Capability Store wordt opgeslagen in ACPI. Het is een statische beschrijving van de mogelijkheden van het systeem en elk van de USB-Type-C-connectors die de DPM gebruikt om het beleid te bepalen dat moet worden geïmplementeerd.

    Door de beschrijving van de systeemmogelijkheden van het clientstuurprogramma voor de poortcontroller(s) te scheiden, kan een stuurprogramma worden gebruikt op verschillende systemen met verschillende mogelijkheden. UcmCx, niet UcmTcpciCx, interfaceert met de Capability Store. UcmTcpciCx (of het bijbehorende clientstuurprogramma) communiceert niet met de Capability Store.

    Waar van toepassing overschrijft de informatie uit de Capability Store informatie die rechtstreeks afkomstig is van het clientstuurprogramma van de poortcontroller. Een poortcontroller kan bijvoorbeeld alleen sinkbewerkingen uitvoeren en het clientstuurprogramma rapporteert die informatie. De rest van het systeem is echter mogelijk niet juist geconfigureerd voor alleen-sinkbewerkingen. In dat geval kan de fabrikant van het systeem melden dat de connectoren alleen als bron operationeel zijn in de Capability Store. De instelling in de Capability Store heeft voorrang op de door het stuurprogramma gerapporteerde informatie.

  • Informeer UcmTcpciCx met alle relevante gegevens met betrekking tot de waarschuwingen.

  • Facultatief. Voer extra verwerking uit nadat een alternatieve modus is ingevoerd/afgesloten. Het stuurprogramma wordt geïnformeerd over deze statussen door de klasse-extensie via IOCTL requests.

Het clientstuurprogramma registreren bij UcmTcpciCx

Voorbeeldreferentie: Zie EvtPrepareHardware in Device.cpp.

  1. Roep in uw EVT_WDF_DRIVER_DEVICE_ADD implementatie UcmTcpciDeviceInitInitialize aan om de WDFDEVICE_INIT ondoorzichtige structuur te initialiseren. De aanroep koppelt het clientstuurprogramma aan het framework.

  2. Nadat u het framework-apparaatobject (WDFDEVICE) hebt gemaakt, roept u UcmTcpciDeviceInitialize aan om de client duiker te registreren bij UcmTcpciCx.

Het I2C-communicatiekanaal initialiseren naar de poortcontrollerhardware

Voorbeeldreferentie: Zie EvtCreateDevice in Device.cpp.

In uw EVT_WDF_DEVICE_PREPARE_HARDWARE-implementatie leest u de hardwarebronnen uit om een communicatiekanaal te openen. Dit is vereist voor het ophalen van de mogelijkheden van PD en het ontvangen van meldingen.

De meeste TCPCI-controllers zijn I2C-verbonden. In het referentievoorbeeld opent het clientstuurprogramma een I2-kanaal met behulp van de SPB Framework Extension (SpbCx) programmeerinterface.

Het clientstuurprogramma inventariseert de hardwareresources door WdfCmResourceListGetDescriptor aan te roepen.

Waarschuwingen worden als interrupts ontvangen. Het stuurprogramma maakt daarom een framework-interruptobject en registreert de ISR die de waarschuwingen afhandelt. De ISR voert hardware lees- en schrijfbewerkingen uit, die blokkeren totdat de hardwaretoegang is voltooid. Omdat wachten onacceptabel is bij DIRQL, voert de bestuurder de ISR uit op PASSIVE_LEVEL.

De Type-C- en PD-mogelijkheden van de poortcontroller initialiseren

Voorbeeldreferentie: Zie EvtDeviceD0Entry in Device.cpp.

In uw EVT_WDF_DEVICE_D0_EXIT-implementatie,

  1. Communiceer met de poortcontrollerhardware en haal apparaatidentificatie en -mogelijkheden op door verschillende registers te lezen.

  2. Initialiseer UCMTCPCI_PORT_CONTROLLER_IDENTIFICATION en UCMTCPCI_PORT_CONTROLLER_CAPABILITIES met de opgehaalde gegevens.

  3. Initialiseer UCMTCPCI_PORT_CONTROLLER_CONFIG structuur met de voorgaande informatie door de geïnitialiseerde structuren door te geven aan UCMTCPCI_PORT_CONTROLLER_CONFIG_INIT.

  4. Roep UcmTcpciPortControllerCreate aan om het poortcontrollerobject te maken en de UCMTCPCIPORTCONTROLLER-ingang op te halen.

Een frameworkwachtrijobject instellen voor het ontvangen van aanvragen van UcmTcpciCx

Voorbeeldreferentie: Zie EvtDeviceD0Entry in Device.cpp en HardwareRequestQueueInitialize in Queue.cpp.

  1. Maak in uw EVT_WDF_DEVICE_D0_EXIT-implementatie een frameworkwachtrijobject door WdfIoQueueCreate aan te roepen. In die aanroep moet u uw callback-implementatie registreren om IOCTL-aanvragen te verwerken die door UcmTpciCx worden verzonden. Het clientstuurprogramma kan een door energie beheerde wachtrij gebruiken.

    Tijdens de uitvoering van de Type-C- en PD-statusmachines verzendt UcmTpciCx opdrachten naar het clientstuurprogramma om uit te voeren. UcmTcpciCx garandeert op elk gewenst moment maximaal één openstaande aanvraag voor de poortcontroller.

  2. Roep UcmTcpciPortControllerSetHardwareRequestQueue aan om het nieuwe framework wachtrijobject te registreren bij UcmTpciCx. Nadat deze aanroep is geslaagd, plaatst UcmTcpciCx framework queue objects (WDFREQUEST) in deze wachtrij wanneer er actie van het stuurprogramma is vereist.

  3. Implementeer de callback-functie EvtIoDeviceControl om deze IOCTL's af te handelen.

Besturingscode Beschrijving
IOCTL_UCMTCPCI_PORT_CONTROLLER_GET_STATUS Hiermee worden waarden van alle statusregisters opgehaald volgens de Universal Serial Bus Type-C Port Controller Interface Specification. Het clientstuurprogramma moet de waarden van de CC_STATUS, POWER_STATUS en FAULT_STATUS registers ophalen.
IOCTL_UCMTCPCI_PORT_CONTROLLER_GET_CONTROL Hiermee haalt u de waarden op van alle controleregisters die zijn gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_CONTROL Hiermee stelt u de waarde in van een besturingsregister dat is gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_TRANSMIT Hiermee stelt u het TRANSMIT-register in dat is gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_TRANSMIT_BUFFER Hiermee stelt u het TRANSMIT_BUFFER Register in, zoals gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specificatie.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_RECEIVE_DETECT Hiermee stelt u het RECEIVE_DETECT Register in dat is gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specificatie.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_CONFIG_STANDARD_OUTPUT Hiermee stelt u de CONFIG_STANDARD_OUTPUT Register in zoals gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_COMMAND Hiermee stelt u de waarde van een opdrachtregister dat is gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_MESSAGE_HEADER_INFO Hiermee stelt u de waarde van het MESSAGE_HEADER_INFO Register dat is gedefinieerd volgens de Universal Serial Bus Type-C Port Controller Interface Specification.
IOCTL_UCMTCPCI_PORT_CONTROLLER_ALTERNATE_MODE_ENTERED Hiermee wordt het clientstuurprogramma gemeld dat er een alternatieve modus wordt ingevoerd, zodat het stuurprogramma andere taken kan uitvoeren.
IOCTL_UCMTCPCI_POORTCONTROLLER_ALTERNATE_MODE_UITGESCHAKELD Hiermee wordt het clientstuurprogramma op de hoogte gebracht dat een alternatieve modus is afgesloten, zodat het stuurprogramma andere taken kan uitvoeren.
IOCTL_UCMTCPCI_PORT_CONTROLLER_DISPLAYPORT_CONFIGURED Hiermee wordt het clientstuurprogramma op de hoogte gebracht dat de alternatieve modus displayPort op het partnerapparaat is geconfigureerd met pincodetoewijzing, zodat het stuurprogramma andere taken kan uitvoeren.
IOCTL_UCMTCPCI_PORT_CONTROLLER_DISPLAYPORT_HPD_STATUS_CHANGED Hiermee wordt het clientstuurprogramma gemeld dat de hot-plug-detectiestatus van de DisplayPort-verbinding is gewijzigd, zodat het stuurprogramma andere taken kan uitvoeren.
  1. Roep UcmTcpciPortControllerStart aan om UcmTcpciCx te instrueren om de poortcontroller te starten. UcmTcpciCx neemt de controle over USB Type-C en Power Delivery over. Nadat de poortcontroller is gestart, kan UcmTcpciCx beginnen met het plaatsen van aanvragen in de wachtrij voor hardwareaanvragen.

Waarschuwingen van de poortcontrollerhardware verwerken

Voorbeeldreferentie: Zie ProcessAndSendAlerts in Alert.cpp

Het clientstuurprogramma moet waarschuwingen (of gebeurtenissen) verwerken die zijn ontvangen van de poortcontrollerhardware en deze verzenden naar UcmTcpciCx met gegevens die betrekking hebben op de gebeurtenis.

Wanneer er een hardwarewaarschuwing optreedt, zet de hardware van de poortcontroller de ALERT-pinned hoog. Dit zorgt ervoor dat de ISR van het clientstuurprogramma (geregistreerd in stap 2) wordt aangeroepen. De routine bedient de hardware-interrupt bij PASSIVE_LEVEL. De routine bepaalt of een interrupt een waarschuwing is van de poortcontrollerhardware; als dat het geval is, wordt de verwerking van de waarschuwing voltooid en wordt UcmTcpciCx op de hoogte gesteld door UcmTcpciPortControllerAlert aan te roepen.

Voordat u UcmTcpciPortControllerAlert aanroept, is de client verantwoordelijk voor het opnemen van alle relevante gegevens die betrekking hebben op de waarschuwing in een UCMTCPCI_PORT_CONTROLLER_ALERT_DATA structuur. De client biedt een matrix van alle waarschuwingen die actief zijn, omdat er een mogelijkheid is dat de hardware meerdere waarschuwingen tegelijk kan bevestigen.

Hier volgt een voorbeeldstroom van taken voor het rapporteren van wijzigingen in CC-status.

  1. Client ontvangt een hardwarewaarschuwing.

  2. Client leest het WAARSCHUWINGsregister en bepaalt het type waarschuwingen dat actief is.

  3. Client leest het CC STATUS-register en beschrijft de inhoud van het CC STATUS-register in UCMTCPCI_PORT_CONTROLLER_ALERT_DATA. Het stuurprogramma stelt het AlertType-lid in op UcmTcpciPortControllerAlertCCStatus en het CCStatus-lid van het register.

  4. Client roept UcmPortControllerAlert aan om de matrixhardwarewaarschuwingen naar UcmTcpciCx te verzenden.

  5. Client wist de waarschuwing (dit kan op elk moment gebeuren nadat de Client de waarschuwingsgegevens heeft opgehaald)

Aanvragen verwerken die zijn ontvangen van UcmTcpciCx

Voorbeeldreferentie: Zie PortControllerInterface.cpp

Als onderdeel van de uitvoering van statuscomputers moet UcmTcpciCx aanvragen verzenden naar de poortcontroller. De TRANSMIT_BUFFER moet bijvoorbeeld worden ingesteld. Deze aanvraag wordt doorgegeven aan de clientdriver. Het stuurprogramma stelt de verzendbuffer in met de details verstrekt door UcmTcpciCx. De meeste van deze aanvragen worden omgezet in een hardware die wordt gelezen of geschreven door het clientstuurprogramma. De opdrachten moeten asynchroon zijn omdat de DPM niet kan blokkeren totdat een hardwareoverdracht is voltooid.

UcmTcpciCx verzendt de opdrachten als I/O-besturingscode die de get/set-bewerking beschrijft die vereist is vanuit het clientstuurprogramma. In de wachtrij-installatie van het clientstuurprogramma heeft het stuurprogramma de wachtrij geregistreerd bij UcmTcpciCx. UcmTcpciCx begint met het plaatsen van frameworkaanvraagobjecten in de wachtrij waarvoor bewerking van het stuurprogramma is vereist. De I/O-besturingscodes worden vermeld in de tabel in stap 4.

Het is de verantwoordelijkheid van het clientstuurprogramma om aanvragen tijdig te voltooien.

Het clientstuurprogramma roept WdfRequestComplete aan op het frameworkaanvraagobject met een voltooiingsstatus wanneer de aangevraagde bewerking is voltooid.

Het clientstuurprogramma moet mogelijk een I/O-aanvraag verzenden naar een ander stuurprogramma om de hardwarebewerking uit te voeren. In het voorbeeld verzendt het stuurprogramma bijvoorbeeld een SPB-aanvraag naar de met I2C verbonden poortcontroller. In dat geval kan het stuurprogramma het frameworkaanvraagobject dat het heeft ontvangen van UcmTcpciCx niet doorsturen omdat het aanvraagobject mogelijk niet het juiste aantal stacklocaties in de WDM IRP heeft. Het clientstuurprogramma moet een ander frameworkaanvraagobject maken en doorsturen naar een ander stuurprogramma. Het clientstuurprogramma kan de aanvraagobjecten die nodig zijn tijdens de initialisatie vooraf indelen, in plaats van iedere keer dat er een aanvraag van UcmTcpciCx binnenkomt, er een te maken. Dit is mogelijk omdat UcmTcpciCx garandeert dat er op elk moment slechts één aanvraag openstaand is.

Zie ook