繁体   English   中英

如何以编程方式拔出并重新插入任意USB设备?

[英]How to programmatically unplug & replug an arbitrary USB device?

我正在尝试修复伪装成虚拟COM端口的无响应USB设备。 手动重新插入可以工作,但其中最多可以包含12个。 是否有API命令可以执行与拔出/重新插入周期等效的编程?

使用Devcon.exe“删除”然后“重新扫描”怎么办?

博士

您可以使用C#硬件帮助程序库并添加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;  
}  

不幸的是,我没有一个知道。 物理上拔下USB连接会通过上拉电阻执行特定的电子操作,从而使设备知道已拔下。 我还没有遇到一个试图在不物理拔出的情况下模拟这种情况的主机。

想法:在“设备管理器”下,您可以右键单击计算机图标(在设备树顶部),然后“扫描更改”。 我不确定100%,但是我认为,如果您“弹出” USB设备(等效于软件“拔出”),然后扫描“查找硬件更改”,即使它从未真正离开端口,它也会备份显示。

如果我对此表示正确,则可以使用Microsoft.Win32.Shell类来模拟打开控制面板->管理工具->设备管理器并运行上下文菜单项。 无论如何,值得一试。

以下是一些指导性的指导:

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

这是更顽固的:

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

我会说使用devcon.exe可能会解决一些问题,但不是我的。 假设您可以构建一个带有USB端口阵列的盒子,其中电源线被MCU控制的FET中断。 MCU应该说一些基本而可靠的内容,例如RS-232。 可能会有一个arduino板简化了可怕的硬件工作。

正如格雷格·休吉尔(Greg Hewgill)所说,我认为这是不可能的。

整个USB启动的启动是由USB从设备(在您的情况下为设备)触发的。 USB主机(PC)可以向设备发送一条消息,告诉它关闭,但是一旦完成,就由设备重新启动。 主机不能强迫它。

更糟糕的是,您很可能会发现USB设备正在检测正在插入的插头(通过检测电源线上的USB电压)以启动。 对于总线供电的设备尤其如此。


听起来您的情况和尝试卸下/重新安装USB驱动器的情况有所不同。 卸载USB驱动器后,没有理由无法在PC上枚举它。 您实际上并没有重置USB驱动器,只是使它的文件系统处于非活动状态。

我已经将其用于自动化测试。 我们想出的最好的解决方案似乎是USB集线器能够在设备消耗过多功率时断开它们的连接。 从USB角度来看,似乎USB主机可能指示集线器这样做。 使用12台设备,您将拥有集线器,因此建议您调查该路径。

前一段时间,我不得不为我的车载计算机项目执行此操作。 触摸屏驱动程序不喜欢进入休眠状态,因此当计算机从休眠状态恢复时,需要重新插入触摸屏驱动程序。 我最终解决它的方法是使用DigitalRacer建议的Devcon.exe。 但是,窍门是在控制器上执行删除/重新扫描操作无效。 我必须在设备上游的HUB上执行删除/重新扫描(随后断开所有连接的设备的连接)。

如果您在任何特定主机上都具有多个端口,则可以将它们插入计算机专用的USB集线器中,从而节省一些时间/烦恼-至少只有一根电缆可以拔出/重新启动,以便重新启动一次设备。

当然,您可能已经想到了。 :-)

我们使用来可编程断开USB设备的连接。

设备本身可以执行此操作(即执行USB断开/重新连接顺序)。

您是否已联系设备制造商,或者如果您是制造商,请联系设计它的EE?

在设计USB嵌入式设备时,我必须这样做-可以通过USB完成编程,但是该设备必须能够断开并重新连接好几个点才能完成该过程。

除此之外,还有一种蛮力方法,即在设备管理器中禁用USB主机设备(我认为这可以在软件中完成),然后重新启用它。

如果没有其他问题,Phidg​​et拥有USB控制的中继板,您可以使用它们将电源或USB线本身连接到集线器或单个设备。

-亚当

可以通过编程方式卸载USB驱动器 ,但是,我不知道是否可以通过代码完成卸载

使用C#代码项目弹出USB磁盘中,查找以下内容:

CM_Request_Device_Eject函数

这是用来弹出设备(可以弹出的任何设备)的SetupApi函数。 它以设备实例句柄(或devInst)作为输入...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM