web-dev-qa-db-fra.com

Comment débrancher et rebrancher par programmation un périphérique USB arbitraire?

J'essaie de réparer un périphérique USB non réactif qui se fait passer pour un port COM virtuel. La réinstallation manuelle fonctionne, mais il peut y avoir jusqu'à 12 de ces unités. Existe-t-il une commande API pour effectuer l'équivalent programmatique du cycle de débranchement/replugage?

34
Dean

Qu'en est-il de l'utilisation de Devcon.exe pour "supprimer" puis "réanalyser"?

DR

9
DigitalRacer

Vous pouvez utiliser Libérateur d'aide matérielle C # et ajouter fonction ResetDevice .

public bool ResetDevice( IntPtr hDevInfo, IntPtr devInfoData )  
// Need to add  
// public const int DICS_PROPCHANGE = ((0x00000003));   
// at the public class Native under //PARMS  
int szOfPcp;  
IntPtr ptrToPcp;  
int szDevInfoData;  
IntPtr ptrToDevInfoData;  

Native.SP_PROPCHANGE_PARAMS pcp = new Native.SP_PROPCHANGE_PARAMS();  
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));  
pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;  
pcp.StateChange = Native.DICS_PROPCHANGE; // for reset  
pcp.Scope = Native.DICS_FLAG_CONFIGSPECIFIC;  
pcp.HwProfile = 0;  

szOfPcp = Marshal.SizeOf(pcp);  
ptrToPcp = Marshal.AllocHGlobal(szOfPcp);  
Marshal.StructureToPtr(pcp, ptrToPcp, true);  
szDevInfoData = Marshal.SizeOf(devInfoData);  
ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);  
Marshal.StructureToPtr(devInfoData, ptrToDevInfoData, true);  

bool rslt1 = Native.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp,   Marshal.SizeOf(typeof(Native.SP_PROPCHANGE_PARAMS)));  
bool rstl2 = Native.SetupDiCallClassInstaller(Native.DIF_PROPERTYCHANGE, hDevInfo,   ptrToDevInfoData);  

if (rslt1 && rstl2)  
{  
    return true;  
}  
return false;  
}  
4
shahar_m

Malheureusement, il n'y en a pas que je sache. Débrancher physiquement la connexion USB fait des choses électroniques spécifiques avec des résistances de pullup, de sorte que l'appareil sait qu'elle est débranchée. Je n'ai pas rencontré d'hôte qui tente de pouvoir simuler cette condition sans débranchement physique.

3
Greg Hewgill

Réflexion: sous le Gestionnaire de périphériques, vous pouvez cliquer avec le bouton droit sur l'icône de votre ordinateur (en haut de l'arborescence des périphériques) et "rechercher les modifications". Je ne suis pas sûr à 100%, mais je pense que si vous "éjectez" un périphérique USB (équivalent du logiciel "débrancher"), puis recherchez les modifications matérielles, il s'affichera même s'il n'a jamais quitté le port.

Si j'ai raison à ce sujet, vous pourrez peut-être utiliser la classe Microsoft.Win32.Shell pour émuler l'ouverture du Panneau de configuration -> Outils d'administration -> Gestionnaire de périphériques et exécuter l'élément de menu contextuel. Ça vaut le coup, de toute façon.

2
Coderer

J'ai dû le faire pour mon projet d'ordinateur de voiture il y a quelque temps. Les pilotes d'écran tactile n'aimaient pas entrer en veille prolongée et devaient être rebranchés lorsque l'ordinateur revenait de la mise en veille prolongée. La façon dont j'ai fini par le résoudre était d'utiliser Devcon.exe comme l'a suggéré DigitalRacer. L'astuce cependant, était que la suppression/nouvelle analyse sur le contrôleur ne fonctionnait pas. J'ai dû faire la suppression/nouvelle analyse sur un HUB en amont de l'appareil (qui a ensuite déconnecté tous les appareils connectés).

1
Dolphin

J'ai regardé cela pour des tests automatisés. La meilleure solution que nous avons trouvée semble être la capacité des concentrateurs USB à déconnecter les appareils lorsqu'ils consomment trop d'énergie. D'un point de vue USB, il semble que l'hôte USB puisse demander à un concentrateur de le faire. Avec 12 appareils, vous aurez des hubs, donc je vous suggère d'enquêter sur ce chemin.

1
MSalters

Voici quelques conseils pratiques:

http://digital.ni.com/public.nsf/allkb/1D120A90884C25AF862573A700602459

C'est plus hardcore:

http://support.Microsoft.com/kb/311272

Je dirais que l'utilisation de devcon.exe peut résoudre certains problèmes, pas le mien. Supposons que vous puissiez construire une boîte avec des matrices de ports USB, où la ligne électrique est interrompue avec des FET contrôlés par un MCU. Le MCU devrait parler de quelque chose de basique et fiable, comme RS-232. Il pourrait y avoir une carte Arduino qui simplifie le travail matériel effrayant.

1
NoJoshua

Comme Greg Hewgill l'a dit, je ne pense pas que ce soit possible.

L'initiation de l'ensemble du démarrage USB est déclenchée par l'esclave USB (dans votre cas, votre appareil). L'hôte USB (le PC) peut envoyer un message à l'appareil pour lui dire de s'éteindre, mais une fois que c'est fait, c'est à l'appareil de redémarrer. L'hôte ne peut pas le forcer.

Pour aggraver les choses, vous constaterez très probablement que le périphérique USB détecte la prise insérée (en détectant la tension USB sur les lignes électriques) pour démarrer. Cela est particulièrement vrai pour les appareils alimentés par bus.


Il semble qu'il y ait des différences par rapport à votre situation et au cas où vous essayez de démonter/remonter des lecteurs USB. Lorsque le lecteur USB est démonté, il n'y a aucune raison qu'il ne puisse pas être énuméré sur le PC. Vous ne réinitialisez pas réellement le lecteur USB, vous ne faites que rendre son système de fichiers inactif.

1
Andrew Edgecombe

Nous avons utilisé this pour déconnecter les périphériques USB programmables.

0
Ilya

Si vous en avez plusieurs sur une machine hôte particulière, vous pouvez économiser du temps/de la frustration en les branchant sur leur propre concentrateur USB dédié à partir de la machine - au moins ce n'est qu'un seul câble à débrancher/brancher pour redémarrer quelques appareils à la fois.

Vous y avez probablement pensé, bien sûr. :-)

0
robsoft

Le périphérique lui-même peut être en mesure de le faire (c'est-à-dire d'effectuer une séquence de déconnexion/reconnexion USB).

Avez-vous contacté le fabricant de l'appareil, ou si vous êtes le fabricant, les EE qui l'ont conçu?

J'ai dû le faire lorsque j'ai conçu un périphérique USB intégré - la programmation pouvait être effectuée via USB, mais le périphérique devait être capable de se déconnecter et de se reconnecter à plusieurs moments pour terminer le processus.

Au-delà de cela, il y a la méthode de force brute pour désactiver le périphérique hôte USB dans le gestionnaire de périphériques (je suppose que cela peut être fait dans le logiciel), puis le réactiver.

Si rien d'autre, Phidget a des cartes relais contrôlées par USB que vous pouvez utiliser pour connecter l'alimentation ou les lignes USB elles-mêmes aux concentrateurs ou aux appareils individuels.

-Adam

0
Adam Davis