Comment envoyer un transfert de contrôle USB (application UWP)

Cet article illustre les points suivants :

  • Comment mettre en forme un paquet d’installation USB
  • Comment lancer un transfert de contrôle USB à partir de votre application

API importantes

Une application qui communique avec un périphérique USB envoie généralement plusieurs demandes de transfert de contrôle. Ces demandes obtiennent des informations sur l’appareil et envoient des commandes de contrôle définies par le fournisseur de matériel. Dans cette rubrique, vous allez découvrir les transferts de contrôle et la façon de les mettre en forme et de les envoyer dans votre application UWP.

Un transfert de contrôle peut lire ou écrire des informations de configuration ou effectuer des fonctions spécifiques à l’appareil définies par le fournisseur de matériel. Si le transfert effectue une opération d’écriture, il s’agit d’un transfert OUT ; une opération de lecture, il s’agit d’un transfert IN. Quelle que soit la direction, un logiciel, tel que votre application UWP, sur le système hôte génère et lance toujours une demande de transfert de contrôle. Parfois, votre application peut lancer des transferts de contrôle qui lit ou écrit des données. Dans ce cas, vous devrez peut-être envoyer une mémoire tampon supplémentaire.

Pour prendre en charge tous les types de transferts de contrôle, Windows.Devices.Usb fournit les méthodes suivantes :

Transfert de contrôle usb pour les API windows runtime pour usb.

Les transferts de contrôle USB sont également utilisés pour obtenir des données de descripteur ou envoyer des commandes standard. Toutefois, nous vous recommandons d’envoyer ces types de requêtes en appelant des méthodes spécifiques fournies par Windows.Devices.Usb plutôt que de créer un transfert de contrôle manuellement. Par exemple, pour sélectionner un autre paramètre, appelez SelectSettingAsync au lieu d’appeler SendControlOutTransferAsync (UsbSetupPacket).

Les transferts de contrôle pour certains types de requêtes standard ne sont pas pris en charge. Toutefois, si votre appareil appartient à une classe d’appareil prise en charge par Windows.Devices.Usb, vous pouvez envoyer des requêtes comme défini par la spécification de la classe d’appareil.

Avant de commencer

  • Vous devez ouvrir l’appareil et obtenir l’objet UsbDevice . Consultez Comment se connecter à un périphérique USB (application UWP).
  • Obtenir des informations sur les commandes de contrôle définies par le fournisseur. Ces commandes sont généralement définies dans la spécification matérielle.
  • Vous pouvez voir le code complet présenté dans cette rubrique dans l’exemple CustomUsbDeviceAccess, Scenario2_ControlTransfer.cpp et Scenario2_ControlTransfer.h.

Étape 1 : Remplir le paquet d’installation

Dans cette rubrique, nous allons envoyer un transfert de contrôle à un appareil qui clignote dans différents modèles. Pour remplir le paquet d’installation, vous devez savoir que les commandes de contrôle sont définies par le fournisseur de matériel :

  • bmRequestType (D7) : OUT
  • bmRequestType (D4) : appareil
  • bmRequestType (D6... D5) : Fournisseur
  • bRequest : 0x03
  • wValue : 0-7 (n’importe quel nombre dans cette plage, inclus)
  • wIndex : 0
  • wLength : 0

Pour le transfert de contrôle, vous devez remplir un paquet d’installation qui contient toutes les informations sur le transfert ; si la requête lit ou écrit des données, le type de requête, etc. Le format du paquet d’installation est défini dans la spécification USB officielle. Les valeurs des champs de paquets d’installation sont fournies par la spécification matérielle de l’appareil.

  1. Créez un objet UsbSetupPacket .

  2. Remplissez l’objet UsbSetupPacket en définissant différentes propriétés. Ce tableau montre les champs de paquets d’installation définis par USB et les propriétés qui correspondent à ces champs :

    Champs de la section 9.3 Propriété Description
    bmRequestType (D7) UsbControlRequestType.Direction Direction de la demande. Indique si la demande est de l’hôte à l’appareil (transferts sortants) ou de l’appareil à l’hôte (Dans les transferts)
    bmRequestType (D4) UsbControlRequestType.Recipient Destinataire de la demande. Tous les transferts de contrôle ciblent le point de terminaison par défaut. Toutefois, le destinataire peut être un appareil, une interface, un point de terminaison ou autre. Pour plus d’informations sur le périphérique USB, l’interface et la hiérarchie des points de terminaison, consultez Disposition de l’appareil.
    bmRequestType (D6... D5) UsbControlRequestType.ControlTransferType Catégorie de requête. Standard, classe ou fournisseur.
    bRequest UsbSetupPacket.Request Type de la demande. Si la demande est une requête standard, telle qu’une demande de GET_DESCRIPTOR, cette demande est définie par la spécification USB. Sinon, il peut être défini par le fournisseur.
    wValue UsbSetupPacket.Value Dépend du type de requête.
    Windex UsbSetupPacket.Index Dépend du type de requête.
    wLength UsbSetupPacket.Length Longueur du paquet de données envoyé ou reçu dans cette demande.

! [REMARQUE] Pour certains transferts de contrôle, vous devrez peut-être fournir bmRequestType en tant qu’octet brut. Dans ce cas, vous pouvez définir l’octet dans la propriété UsbControlRequestType.AsByte .

Étape 2 : Démarrer une opération asynchrone pour envoyer le transfert de contrôle

Pour envoyer des transferts de contrôle, vous devez disposer d’un objet UsbDevice . Votre transfert de contrôle peut nécessiter ou non des paquets de données qui suivent le paquet d’installation.

Pour lancer un transfert de contrôle, appelez le remplacement de SendControlInTransferAsync ou SendControlOutTransferAsync. Si le transfert utilise des paquets de données, appelez SendControlOutTransferAsync (UsbSetupPacket, IBuffer),SendControlInTransferAsync (UsbSetupPacket, IBuffer). Ces méthodes prennent un paramètre supplémentaire qui contient les données à écrire ou reçoit des données de l’appareil. Utilisez l’organigramme pour déterminer le remplacement à appeler.

L’appel démarre et l’opération asynchrone. Une fois l’opération terminée, l’appel retourne l’objet IAsyncOperation qui contient les résultats de l’opération. Pour un transfert OUT, l’objet retourne le nombre d’octets envoyés dans un transfert. Pour un transfert IN, l’objet contient la mémoire tampon qui contient les données lues à partir de l’appareil.

Exemple de code de transfert de contrôle USB

Cet exemple de code montre comment envoyer un transfert de contrôle qui modifie le modèle de clignotement sur l’appareil SuperMUTT. Le paquet d’installation du transfert contient une commande définie par le fournisseur. L’exemple se trouve dans Scenario2_ControlTransfer.cpp.

async Task SetSuperMuttLedBlinkPatternAsync(Byte pattern)
        {
            UsbSetupPacket initSetupPacket = new UsbSetupPacket
            {
                RequestType = new UsbControlRequestType
                {
                    Direction = UsbTransferDirection.Out,
                    Recipient = UsbControlRecipient.Device,
                    ControlTransferType = UsbControlTransferType.Vendor
                },
                Request = SuperMutt.VendorCommand.SetLedBlinkPattern,
                Value = pattern,
                Length = 0
            };

            UInt32 bytesTransferred = await EventHandlerForDevice.Current.Device.SendControlOutTransferAsync(initSetupPacket);

            MainPage.Current.NotifyUser("The Led blink pattern is set to " + pattern.ToString(), NotifyType.StatusMessage);
        }

Cet exemple de code montre comment envoyer un transfert de contrôle qui modifie le modèle de clignotement sur l’appareil SuperMUTT. Le paquet d’installation du transfert contient une commande définie par le fournisseur. L’exemple se trouve dans Scenario2_ControlTransfer.cpp.

async Task<IBuffer> SendVendorControlTransferInToDeviceRecipientAsync(Byte vendorCommand, UInt32 dataPacketLength)
 {
    // Data will be written to this buffer when we receive it
    var buffer = new Windows.Storage.Streams.Buffer(dataPacketLength);

    UsbSetupPacket initSetupPacket = new UsbSetupPacket
    {
        RequestType = new UsbControlRequestType
        {
            Direction = UsbTransferDirection.In,
            Recipient = UsbControlRecipient.Device,
            ControlTransferType = UsbControlTransferType.Vendor,
        },
        Request = vendorCommand,
        Length = dataPacketLength
    };

    return await EventHandlerForDevice.Current.Device.SendControlInTransferAsync(initSetupPacket, buffer);
}