Windows下libusb与STM32 CDC设备通信报LIBUSB_ERROR_NOT_FOUND问题
STM32F446RE USB CDC设备Windows下libusb批量传输失败
背景
我用STM32F446RE制作了一款基础通信类USB设备,设备每秒发送一段文本。基于libusb编写的跨平台读取程序在Linux下运行正常,流程为:
- 列出所有设备
- 通过VID和PID筛选目标设备
- 打开设备
- 分离内核驱动
- 占用接口
- 提交批量传输接收数据并打印到终端
Windows下的问题
迁移到Windows后,首先遇到打开设备时的LIBUSB_ERROR_NOT_SUPPORTED错误。经查Windows默认不为USB CDC设备提供驱动,使用Zadig工具安装WinUSB通用驱动并移除分离内核驱动的代码后,设备可正常打开,但提交批量传输时出现LIBUSB_ERROR_NOT_FOUND错误。
调试日志(调试级别4)
[ 0.077542] [00005830] libusb: debug [libusb_open] open 3.2 [ 0.078566] [000022f0] libusb: debug [libusb_claim_interface] interface 0 [ 0.078694] [000022f0] libusb: debug [winusbx_claim_interface] claimed interface 0 [ 0.079206] [000022f0] libusb: debug [windows_assign_endpoints] (re)assigned endpoint 82 to interface 0 [ 0.079853] [00000280] libusb: debug [windows_iocp_thread] ignoring overlapped 000000FB54DFF8D0 for handle 000002181F1A3310 [ 0.080480] [00000280] libusb: debug [windows_iocp_thread] ignoring overlapped 000000FB54DFF8D0 for handle 000002181F1A3310 [ 0.081122] [000022f0] libusb: debug [libusb_submit_transfer] transfer 000002181F1930E0 [ 0.081842] [00000280] libusb: debug [windows_iocp_thread] ignoring overlapped 000000FB54DFF8D0 for handle 000002181F1A3310 [ 0.085782] [000022f0] libusb: debug [add_to_flying_list] arm timer for timeout in 2000ms (first in line) [ 0.086302] [00000280] libusb: debug [windows_iocp_thread] ignoring overlapped 000000FB54DFF8D0 for handle 000002181F1A3310 [ 0.086975] [000022f0] libusb: error [winusbx_submit_bulk_transfer] unable to match endpoint to an open interface - cancelling transfer [ 0.087657] [00000280] libusb: debug [windows_iocp_thread] ignoring overlapped 000000FB54DFF9B0 for handle 000002181F1A3310 [ 0.088588] [000022f0] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer Failed to submit bulk transfer: LIBUSB_ERROR_NOT_FOUND [ 0.091200] [000022f0] libusb: debug [libusb_free_transfer] transfer 000002181F1930E0 [ 0.091677] [000022f0] libusb: debug [libusb_release_interface] interface 0
我完全无法理解这个问题,比如日志中显示(re)assigned endpoint 82,但我的代码中设置的端点为0x81,这才是设备发送数据的端点。我可以提供USBView的设备详情或更多代码片段。
代码片段
void LIBUSB_CALL bulk_callback(struct libusb_transfer* transfer) { if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { std::cout << "Bulk transfer completed successfully. Received " << transfer->actual_length << " bytes" << std::endl; // 重新提交传输以持续接收数据 int error = libusb_submit_transfer(transfer); if (error < 0) { std::cerr << "Error re-submitting transfer: " << libusb_error_name(error) << std::endl; } } else { std::cerr << "Transfer failed with status: " << libusb_error_name(transfer->status) << std::endl; libusb_free_transfer(transfer); } } int main() { int error = libusb_open(device, &m_selected_device); if (error < 0) { m_working = false; std::cerr << "Error: failed to open device: " << libusb_error_name(error) << std::endl; return; } error = libusb_claim_interface(m_selected_device, INTERFACE_NUMBER); // 0 if (error < 0) { std::cerr << "Error claiming interface: " << libusb_error_name(error) << std::endl; return; } // 通信部分 struct libusb_transfer* transfer = libusb_alloc_transfer(0); if (!transfer) { m_error = true; std::cerr << "Failed to allocate transfer" << std::endl; libusb_release_interface(m_selected_device, INTERFACE_NUMBER); clean_up(); return; } // 分配接收数据的缓冲区 unsigned char* buffer = (unsigned char*) malloc(TRANSFER_SIZE); if (!buffer) { std::cerr << "Failed to allocate buffer" << std::endl; libusb_free_transfer(transfer); libusb_release_interface(m_selected_device, INTERFACE_NUMBER); clean_up(); return; } // 填充批量传输参数:端点、缓冲区、大小、回调函数 libusb_fill_bulk_transfer( transfer, m_selected_device, ENDPOINT_IN, // 0x81 buffer, TRANSFER_SIZE, // 64 bulk_callback, NULL, TIMEOUT ); // 向USB栈提交传输请求 error = libusb_submit_transfer(transfer); if (error < 0) { std::cerr << "Failed to submit bulk transfer: " << libusb_error_name(error) << std::endl; free(buffer); libusb_free_transfer(transfer); libusb_release_interface(m_selected_device, INTERFACE_NUMBER); clean_up(); return; } // 主循环 while (m_working) { error = libusb_handle_events(m_context); if (error < 0) { std::cerr << "Error handling events: " << libusb_error_name(error) << std::endl; break; } } error = libusb_release_interface(m_selected_device, INTERFACE_NUMBER); if (error < 0) { std::cerr << "Error releasing interface: " << libusb_error_name(error) << std::endl; } free(buffer); if (m_selected_device) { libusb_close(m_selected_device); m_selected_device = NULL; } return 0; }
内容的提问来源于stack exchange,提问作者Coffee Spoon
相关产品推荐
相关产品推荐

