Certains appareils disposent de contrôleurs de périphériques USB ou de contrôleurs à double rôle qui peuvent être utilisés en mode hôte ou en mode périphérique.
Cette page vise à documenter comment utiliser et configurer les périphériques gadgets USB OTG sous Linux pour les cartes que vous souhaitez connecter à un port hôte USB et vous comporter comme un « périphérique ».
Les Newport SBC ne prennent pas en charge les modes OTG/Device/Gadget
.
En mode hôte permet de se connecter à un périphérique USB. Aucune configuration particulière n'est nécessaire pour cela.
Le mode périphérique permet la connexion à un hôte USB tel qu'un PC.
Lorsqu'il est utilisé dans ce mode, l'appareil doit avoir un « pilote de gadget » chargé qui implémente la personnalité du type d'appareil souhaité.
Il existe plusieurs pilotes de gadgets Linux dans le noyau Linux actuel. Ceux-ci peuvent être trouvés dans le menu Pilotes de périphérique -> Prise en charge USB -> Prise en charge des gadgets USB
:
Un seul pilote de gadget (personnalité du périphérique) peut être chargé à la fois, mais certains pilotes de gadget « composites » se comportent comme des « périphériques composites », ce qui signifie qu'ils ont plusieurs points de terminaison par périphérique USB. Cela peut s'aparenter au fonctionnement d’un téléphone intelligent moderne. Par exemple un téléphone Android : lorsqu'il est branché sur un PC hôte via micro-USB OTG, il se comportera comme un périphérique de stockage (MTP), mais si on souhaite qu'il se comporte comme un périphérique de débogage série, il faut passer en mode développeur dans le menu système et sélectionner cette option. Les smartphones modernes ne se comportent plus comme des périphériques de « stockage de masse USB », car ce protocole ne permet pas au système d'exploitation de l'appareil d'accéder au système de fichiers en même temps que le PC hôte. Au lieu de cela, ces appareils agissent comme un appareil MTP (Media Transfer Protocol).
L'ID du fournisseur (VID) et l'ID de l'appareil (DID) présentés à l'hôte USB sont configurables
Le pilote du gadget g_ether se comporte comme un dongle USB vers Ethernet. Une fois chargé, le système en mode périphérique ajoutera un périphérique réseau « usb\<n\^> » qui peut être utilisé de la même manière que n'importe quel autre périphérique réseau. Sur le système hôte USB, un périphérique réseau similaire apparaîtra tant qu'un pilote prenant en charge la norme « CDC Ethernet » est disponible.
Ce module peut être construit avec un support supplémentaire :
modprobe g_ether
Remarques sur l'hôte Linux : Le pilote cdc_ether prend en charge cela et créera un périphérique « usb<n> » sur l'hôte USB.
Remarques sur l'hôte Windows: le pilote g_ether est généralement construit avec la prise en charge RNDIS activée, ce qui le rendra compatible avec les pilotes de Windows7 et versions ultérieures qui apparaîtront dans le gestionnaire de périphériques en tant que « Gadget USB Ethernet/RNDIS » et peuvent être configurés comme n'importe quelle autre interface réseau.
Le pilote g_file_storage se comporte comme un périphérique de stockage de masse USB tel qu'un disque dur USB ou une clé USB. Vous pouvez décider d'utiliser un « fichier » comme magasin de sauvegarde ou comme périphérique bloc (c'est-à-dire une partition flash ou un disque physique). Le fichier/périphérique est fourni au module via le paramètre de module 'file'.
Si on utilise un « fichier » de stockage de sauvegarde, il faut le créer au préalable avec la taille souhaitée. Par exemple, pour créer un magasin de sauvegarde de 64 Mo :
dd bs=1M nombre=64 si=/dev/zéro de=/backing_file
Pour l'utiliser comme magasin de sauvegarde :
modprobe g_mass_storage file=/backing_file
Le Serial Gadget prend en charge CDC-ACM et CDC-OBEX qui peuvent interagir avec les hôtes MS-Windows ou Linux en utilisant le pilote « cdc-acm » pour créer une connexion « USB-série ».
modprobe g_serial
Remarques sur l'hôte Linux: le pilote cdc_acm énumérera ce périphérique comme '/dev/ttyACM<n>'
Le gadget g_cdc prend en charge deux fonctions dans une seule configuration :
modprobe g_cdc
Remarques sur l'hôte Linux:
- le pilote cdc_acm énumérera ce périphérique comme '/dev/ttyACM<n>'
- le pilote cdc_ether énumérera ce périphérique comme périphérique réseau 'usb\<n>'
Remarques sur l'hôte Windows:
- Un appareil CDC Composite Gadget apparaîtra dans le Gestionnaire de périphériques
Le gadget g_multi prend en charge plusieurs fonctions dans une seule configuration :
modprobe g_cdc
Remarques sur l'hôte Linux:
- le pilote cdc_acm énumérera ce périphérique comme '/dev/ttyACM\<n>'
- le pilote cdc_ether énumérera ce périphérique comme un 'usb<n>' npériphérique réseau
- le pilote de stockage USB fournira la fonctionnalité de stockage de masse USB
Remarques sur l'hôte Windows:
- Un périphérique Gadget composite multifonction apparaîtra dans le Gestionnaire de périphériques
Le pilote du gadget HID fournit une émulation générique des périphériques d'interface humaine USB (HID), par exemple des claviers, des souris, des écrans tactiles, etc.
modprobe g_hid
Le pilote du gadget g_webcam fournit un périphérique de classe audio et vidéo USB composite.
modprobe g_webcam
/dev/video<n>
sera créé et disponible en tant que périphérique de sortie Video4Linux prenant en charge la vidéo 320/240 YUYV
Remarques sur l'hôte Linux: le pilote uvcvideo énumérera le périphérique et créera un périphérique de capture vidéo /dev/video<n>
Remarques sur l'hôte Windows:
- Un périphérique USB Composite apparaîtra dans le Gestionnaire de périphériques
- Un périphérique de caméra UVC apparaîtra sous Périphériques d'imagerie dans le gestionnaire de périphériques et sera disponible pour capturer des vidéos.
Le pilote de gadget g_ncm fournit une sous-classe USB CDC NCM. NCM est un protocole avancé pour l'encapsulation Ethernet, permettant le regroupement de plusieurs trames Ethernet en un seul transfert USB avec diverses possibilités d'alignement.
modprobe g_ncm
Remarques sur l'hôte Linux: le pilote cdc_ncm énumérera le périphérique et créera une interface réseau dans /sys/class/net
Remarques sur l'hôte Windows: Un appareil NCM Gadget apparaîtra dans le Gestionnaire de périphériques
La prise en charge de Linux Configfs (CONFIG_CONFIGFS_FS/) permet une configuration dynamique complète des périphériques gadgets à partir de l'espace utilisateur, auquel cas on peut créer une configuration unique ou un périphérique composite multi-configuration avec une ou plusieurs des fonctions disponibles dans drivers/usb/gadget/udc/functions
:
Tous les modules de noyau ci-dessus peuvent ne pas être disponibles en fonction de la configuration de votre noyau ou de votre BSP.
# configurations de montage mount -t configfs none /sys/kernel/config # charger le module libcomposite modprobe libcomposite # créer un gadget mkdir /sys/kernel/config/usb_gadget/g1 # cd vers son nœud configfs cd /sys/kernel/config/usb_gadget/g1 # le configurer (vid/pid peut être n'importe quoi si la classe USB est utilisée pour la compatibilité du pilote) echo 0xabcd > idVendor echo 0x1234 > idProduct # configurer son numéro de série/fabricant/produit mkdir strings/0x409 echo myserial > strings/0x409/serialnumber echo mymfg > strings/0x409/manufacturer echo myproduct > strings/0x409/product # créer une configuration mkdir configs/c.1 # configurer avec des attributs si nécessaire echo 120 > configs/c.1/MaxPower # s'assurer que la fonction est chargée modprobe usb_f_acm # créer la fonction (le nom doit correspondre à un module usb_f_<name> tel que 'acm') mkdir functions/acm.0 # associer la fonction à la configuration ln -s functions/acm.0 configs/c.1 # activer le gadget en le liant à un UDC depuis /sys/class/udc echo 0000:01:00.0 > UDC # pour le dissocier : echo "" UDC; sleep 1; rm -rf /sys/kernel/config/usb_gadget/g1
# configurations de montage mount -t configfs none /sys/kernel/config # charger le module libcomposite modprobe libcomposite # créer un gadget mkdir /sys/kernel/config/usb_gadget/g1 # cd vers son nœud configfs cd /sys/kernel/config/usb_gadget/g1 # le configurer (vid/pid peut être n'importe quoi si la classe USB est utilisée pour la compatibilité du pilote) echo 0xabcd > idVendor echo 0x1234 > idProduct # configurer son numéro de série/fabricant/produit mkdir strings/0x409 echo myserial > strings/0x409/serialnumber echo mymfg > strings/0x409/manufacturer echo myproduct > strings/0x409/product # créer une configuration mkdir configs/c.1 # le configurer avec des attributs si nécessaire echo 120 > configs/c.1/MaxPower # s'assurer que la fonction est chargée modprobe usb_f_ecm # créer la fonction (le nom doit correspondre à un module usb_f_<name> tel que 'ecm') fonctions mkdir/ecm.0 # associer la fonction à la configuration ln -s fonctions/ecm.0 configs/c.1 # activer le gadget en le liant à un UDC depuis /sys/class/udc echo 0000:01:00.0 > UDC # pour le dissocier : echo "" UDC; sleep 1; rm -rf /sys/kernel/config/usb_gadget/g1
# configurations de montage mount -t configfs none /sys/kernel/config # charger le module libcomposite modprobe libcomposite # créer un gadget mkdir /sys/kernel/config/usb_gadget/g1 # cd vers son nœud configfs cd /sys/kernel/config/usb_gadget/g1 # le configurer (vid/pid peut être n'importe quoi si la classe USB est utilisée pour la compatibilité du pilote) echo 0xabcd > idVendor echo 0x1234 > idProduct # configurer son numéro de série/fabricant/produit mkdir strings/0x409 echo myserial > strings/0x409/serialnumber echo mymfg > strings/0x409/manufacturer echo myproduct > strings/0x409/product # créer des configurations mkdir configs/c.1 mkdir configs/c.2 mkdir configs/c.3 # les configurer avec des attributs si nécessaire echo 120 > configs/c.1/MaxPower echo 120 > configs/c.2/MaxPower echo 120 > configs/c.2/MaxPower # s'assurer que la fonction est chargée modprobe usb_f_mass_storage # créer la fonction (le nom doit correspondre à un module usb_f_<name> tel que 'acm') mkdir functions/mass_storage.0 # créer un ou plusieurs magasins de sauvegarde : dans cet exemple, 2 LUN de 16 Mo chacun dd bs=1M count=16 if=/dev/zero of=/tmp/lun0.img # 16MB dd bs=1M count=16 if=/dev/zero of=/tmp/lun1.img # 16MB # associer aux partitions mkdir functions/mass_storage.0/lun.0 echo /tmp/lun0.img > functions/mass_storage.0/lun.0/file mkdir functions/mass_storage.0/lun.1 echo /tmp/lun1.img > functions/mass_storage.0/lun.1/file # associer la fonction à la configuration ln -s functions/mass_storage.0 configs/c.1 # activer le gadget en le liant à un UDC depuis /sys/class/udc echo 0000:01:00.0 > UDC # pour le dissocier : echo "" UDC; sleep 1; rm -rf /sys/kernel/config/usb_gadget/g1
OpenWrt regroupe plusieurs des modules du noyau Linux ci-dessus sous forme de packages :
La prise en charge des gadgets doit être activée :
Tous ces packages tenteront de charger automatiquement leur module de noyau respectif, donc celui qui apparaît en premier dans l'ordre alphabétique sera chargé. On peutvoir ce qui est chargé en regardant les modules actuels :
lsmod | grep g_*
Les contrôleurs hôtes USB OTG sont des contrôleurs « à double rôle » dans le sens où ils peuvent se comporter comme un hôte USB ou un périphérique USB. La décision sur le mode dans lequel il se trouve est généralement contrôlée par l'état de la broche d'identification OTG (OTG_ID) qui est mise à la terre sur OTG pour héberger les câbles et laissée flottante sur OTG pour les câbles de périphérique.
Dans certains cas, on peut avoir une carte sans signal OTG_ID sur laquelle on souhaite quand même utiliser USB OTG en mode périphérique.
Les contrôleurs à double rôle peuvent être forcés en mode « hôte » ou en mode « périphérique » via la propriété « dr_mode » de l'arborescence des périphériques. Par exemple, pour forcer un contrôleur IMX6 OTG en mode périphérique, il faut ajouter dr_mode = "peripheral";
au dt tel que :
&usbotg { vbus-supply = <®_5p0v>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg>; disable-over-current; dr_mode = "peripheral"; status = "okay"; };
Cela peut être fait dans le bootloader, voici un exemple pour GW54xx :
setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/aips-bus@2100000/usb@2184000 dr_mode host' # host mode setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/aips-bus@2100000/usb@2184000 dr_mode gadget' # gadget mode saveenv #une fois que vous avez fait votre sélection
De plus, certains contrôleurs hôtes tels que le contrôleur Chips and Media utilisé sur l'IMX6 ont des hooks qui leur permettent d'être configurés au moment de l'exécution dans l'espace utilisateur Linux. Par exemple sur les cartes IMX6 :
cat /sys/kernel/debug/ci_hdrc.0/role # voir le rôle actuel ; valeur par défaut dictée par la propriété dr_mode dt ou l'état de la broche OTG_ID si elle n'est pas définie echo gadget > /sys/kernel/debug/ci_hdrc.0/role # spécifier le mode du périphérique echo host > /sys/kernel/debug/ci_hdrc.0/role # spécifier le mode hôte
Dans certains cas, on peut utiliser une prise USB Type-A en mode appareil de manière non standard. Cela peut être utilisé par exemple sur des cartes qui acheminent un contrôleur USB OTG vers une prise Type-A qui n'a pas de signal OTG_ID. Dans ce cas, il faut soler VBUS pour s'assurer que l'hôte et l'appareil ne le pilotent pas en même temps. Cette opportunité existe sur certaines cartes Ventana (où le contrôleur hôte « usbotg » est activé dans l'arborescence des périphériques mais les signaux sont acheminés vers un connecteur de prise USB Type-A au lieu d'un contrôleur OTG).
Dans ce cas, on peut procéder comme suit :