usb 设备 复位

 

USB devices are anywhere nowadays, even many embedded devices replace the traditional serial devices with usb devices. However, I experienced that USB devices hang from time to time. In most cases, a manual unplug and replug will solve the issue. Actually, usb reset can simulate the unplug and replug operation.

First, get the device path for your usb device. Enter the command lsusb will give you something similar as below,

Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 002: ID 04b3:310c IBM Corp. Wheel Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 002: ID 0a5c:2145 Broadcom Corp.
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Use the IBM Wheel Mouse as an example, the device node for it is /dev/bus/usb/006/002, where 006 is the bus number, and 002 is the device number.

Second, apply ioctl operation to reset the device. This is done in C code,

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
void main(int argc, char **argv)
{
    const char *filename;
    int fd;
    filename = argv[1];
    fd = open(filename, O_WRONLY);
    ioctl(fd, USBDEVFS_RESET, 0);
    close(fd);
    return;
}

Save the code above as reset.c, then compile the code using

gcc -o reset reset.c
32位arm:arm-linux-gnueabihf-gcc

This will produce the a binary named reset. Again, using the wheel mouse as an example, execute the following commands,

sudo ./reset /dev/bus/usb/006/002
 

You can take a look at the message by,

tail -f /var/log/messages
 

On my Ubuntu desktop, the last line reads,

May 4 16:09:17 roman10 kernel: [ 1663.013118] usb 6-2:
reset low speed USB device using uhci_hcd and address 2
 

This reset operation is effectively the same as you unplug and replug a usb device.

For another method of reset usb using libusb, please refer here

转载于:https://www.cnblogs.com/Ph-one/p/11531847.html

### 实现Windows下C++ USB设备复位功能 在Windows环境下,使用C++实现USB设备复位的功能可以通过调用Windows API来完成。以下是一个完整的代码示例,展示如何通过发送 `CLEAR_FEATURE` 请求或直接复位整个USB设备。 #### 1. 使用 `CLEAR_FEATURE` 请求复位特定端点 ```cpp #include <windows.h> #include <setupapi.h> #include <usbioctl.h> #include <iostream> #pragma comment(lib, "setupapi.lib") bool ResetUsbEndpoint(HANDLE hDevice, UCHAR endpointAddress) { // 定义 CLEAR_FEATURE 请求的参数 USB_SETUP_PACKET setupPacket = {0}; setupPacket.bmRequestType = 0x02; // 主机到设备,类请求,接收者为端点 setupPacket.bRequest = USB_REQUEST_CLEAR_FEATURE; setupPacket.wValue = USB_FEATURE_SELECTOR_ENDPOINT_HALT; setupPacket.wIndex = endpointAddress; // 端点地址 setupPacket.wLength = 0; // 发送控制传输以复位端点 DWORD bytesReturned; BOOL result = DeviceIoControl(hDevice, IOCTL_INTERNAL_USB_SUBMIT_URB, &setupPacket, sizeof(setupPacket), NULL, 0, &bytesReturned, NULL); if (!result) { std::cerr << "Failed to reset endpoint: " << GetLastError() << std::endl; return false; } return true; } ``` 上述代码中,通过构造 `USB_SETUP_PACKET` 并调用 `DeviceIoControl` 函数发送了 `CLEAR_FEATURE` 请求以复位指定的USB端点[^1]。 #### 2. 复位整个USB设备 如果需要复位整个USB设备,可以使用 `SetupDiGetClassDevs` 和相关函数找到设备句柄,并调用 `ResetDevice` 方法。 ```cpp bool ResetUsbDevice(HDEVINFO deviceInfoSet, PSP_DEVICE_INTERFACE_DATA deviceInterfaceData) { // 获取设备路径 SP_DEVICE_INTERFACE_DETAIL_DATA* detailData = nullptr; DWORD requiredSize = 0; if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, deviceInterfaceData, nullptr, 0, &requiredSize, nullptr)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { std::cerr << "Error getting device interface detail size: " << GetLastError() << std::endl; return false; } } detailData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)malloc(requiredSize); detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, deviceInterfaceData, detailData, requiredSize, nullptr, nullptr)) { std::cerr << "Error getting device interface detail: " << GetLastError() << std::endl; free(detailData); return false; } // 打开设备句柄 HANDLE hDevice = CreateFile(detailData->DevicePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if (hDevice == INVALID_HANDLE_VALUE) { std::cerr << "Failed to open device: " << GetLastError() << std::endl; free(detailData); return false; } // 发送复位请求 BOOL result = DeviceIoControl(hDevice, IOCTL_USB_RESET_PIPE, nullptr, 0, nullptr, 0, nullptr, nullptr); if (!result) { std::cerr << "Failed to reset device: " << GetLastError() << std::endl; CloseHandle(hDevice); free(detailData); return false; } CloseHandle(hDevice); free(detailData); return true; } ``` 上述代码通过 `IOCTL_USB_RESET_PIPE` 控制码发送了一个复位请求,适用于整个USB设备复位操作[^3]。 #### 3. 设备枚举和初始化 为了找到目标USB设备并获取其句柄,可以使用 `SetupDiGetClassDevs` 函数进行设备枚举。 ```cpp HDEVINFO EnumerateUsbDevices(GUID* classGuid) { HDEVINFO deviceInfoSet = SetupDiGetClassDevs(classGuid, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfoSet == INVALID_HANDLE_VALUE) { std::cerr << "Failed to enumerate USB devices: " << GetLastError() << std::endl; } return deviceInfoSet; } ``` 调用该函数时,需传入目标设备的GUID。例如,对于USB设备,可以使用 `GUID_DEVINTERFACE_USB_DEVICE`。 --- #### 注意事项 - 在执行复位操作之前,确保设备已正确打开并获取了有效的句柄。 - 如果复位失败,可能需要检查设备驱动程序是否正常安装以及是否有权限访问设备。 - 某些USB设备可能对复位操作有特定的要求,请参考设备的具体数据手册或固件文档[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值