执行 libusb_bulk_transfer DataIN ubuntu 操作系统从 USB 设备读取数据时出现 Libusb_Error_IO 错误

发布于 2025-01-11 09:46:42 字数 8067 浏览 0 评论 0原文

提前致谢。我有 2 个 USB 设备(主设备和从设备)。我能够将数据从主设备写入从设备,但无法从从设备读取数据到主设备 USB 设备“LIBUSB_ERROR_IO”错误。该代码具有完全的 root 访问权限。下面是代码和输出。相同的代码在 RHEL 操作系统中运行良好,但在 Ubuntu 中则不行。代码是c++,工具Qt Creator。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <libusb-1.0/libusb.h>

#define EP_DATA_IN 0x81
#define EP_DATA_OUT 0x01
#define DEVICE_CONFIGURATION 0
#define MASTER 0x00f4
#define SLAVE 0x00f2

void writeButtonClicked()
{
int rc;
libusb_context *ctx = NULL;
libusb_device_handle *dev_handle;

QString writeData = "Slave writing !!!";
int actual = writeData.length();
unsigned char *sendData;

sendData = (unsigned char *)malloc(actual);
memcpy(sendData, writeData.toLocal8Bit(), actual);

rc = libusb_init(&ctx);
if(rc < 0) {
std::cout << "Init Error " << rc << std::endl;
}

libusb_set_debug(ctx, 6);


dev_handle = libusb_open_device_with_vid_pid(ctx, 0x04b4, SLAVE); // Give SLAVE or MASTER to perform write operation
if (!dev_handle) {
fprintf(stderr, "Error finding USB device\n");
}

if(libusb_kernel_driver_active(dev_handle, DEVICE_CONFIGURATION) == 1) {
std::cout << "Kernel Driver Active" << std::endl;
if(libusb_detach_kernel_driver(dev_handle, DEVICE_CONFIGURATION) == 0)
std::cout << "Kernel Driver Detached!" << std::endl;
}

rc = libusb_claim_interface(dev_handle, DEVICE_CONFIGURATION);
if(rc != 0) {
std::cout << "Cannot Claim Interface" << std::endl;
rc = libusb_set_interface_alt_setting(dev_handle, DEVICE_CONFIGURATION, 1);
if(rc!=0)
{
std::cout <<"Cannot configure alt setting "<<std::endl;
}
else
{
std::cout <<"configured alt setting "<<std::endl;
}
}

std::cout << "Data->" << sendData << "<-" << std::endl;
std::cout << "Writing Data..." << std::endl;

std::cout << "Trying endpoint " << EP_DATA_OUT << "." << std::endl;
rc = libusb_bulk_transfer(dev_handle, EP_DATA_OUT, sendData, sizeof(sendData), &actual, 1000);

if(rc == 0)
{
std::cout << "Writing Successful!" << std::endl;
}
else
{
std::cout << "Write Error! Rc: " << rc << " Actual transfered bytes: " << actual << "." << std::endl;
std::cout << "Error code means: " << libusb_error_name(rc) << std::endl;
}

rc = libusb_release_interface(dev_handle, 0);
if(rc!=0) {
std::cout << "Cannot Release Interface" << std::endl;
}

if (dev_handle)
libusb_close(dev_handle);

libusb_exit(ctx);
}

void readButtonClicked()
{
int rc;
libusb_context *ctx = NULL;
libusb_device_handle *dev_handle;

int actual = 0;
unsigned char *readData = new unsigned char[512];

rc = libusb_init(&ctx);
if(rc < 0) {
std::cout << "Init Error " << rc << std::endl;
}

libusb_set_debug(ctx, 6);

dev_handle = libusb_open_device_with_vid_pid(ctx, 0x04b4, MASTER); // Give SLAVE or MASTER to perform Read operation
if (!dev_handle) {
fprintf(stderr, "Error finding USB device\n");
}

if(libusb_kernel_driver_active(dev_handle, DEVICE_CONFIGURATION) == 1) {
std::cout << "Kernel Driver Active" << std::endl;
if(libusb_detach_kernel_driver(dev_handle, DEVICE_CONFIGURATION) == 0)
std::cout << "Kernel Driver Detached!" << std::endl;
}

rc = libusb_claim_interface(dev_handle, DEVICE_CONFIGURATION);
if(rc != 0) {
std::cout << "Cannot Claim Interface" << std::endl;
rc = libusb_set_interface_alt_setting(dev_handle, DEVICE_CONFIGURATION, 1);
if(rc!=0)
{
std::cout <<"Cannot configure alt setting "<<std::endl;
}
else
{
std::cout <<"configured alt setting "<<std::endl;
}
}

std::cout << "Trying endpoint " << EP_DATA_IN << "." << std::endl;
rc = libusb_bulk_transfer(dev_handle, EP_DATA_IN, readData, sizeof(readData), &actual, 1000);

if(rc >=0)
{
std::cout << "Read Success! Rc: " << libusb_error_name(rc) << " Actual transfered bytes: " << actual << "." << std::endl;
}
else
{
std::cout << "Read Error! Rc: " << rc << " Actual transfered bytes: " << actual << "." << std::endl;
std::cout << "Error code means: " << libusb_error_name(rc) << std::endl;
}

rc = libusb_release_interface(dev_handle, 0);
if(rc!=0) {
std::cout << "Cannot Release Interface" << std::endl;
}

if (dev_handle)
libusb_close(dev_handle);

libusb_exit(ctx);
}

//Output  Slave writing Master reading
libusb: debug [libusb_get_device_list]
libusb: debug [discovered_devs_append] need to increase capacity
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_open] open 2.16
libusb: debug [usbi_add_pollfd] add fd 26 events 4
libusb: debug [libusb_kernel_driver_active] interface 0
libusb: debug [libusb_claim_interface] interface 0
Data->Slave writing !!!<-
Writing Data...
Trying endpoint 1.
Writing Successful!
libusb: debug [libusb_alloc_transfer] transfer 0x563230a5b760
libusb: debug [libusb_submit_transfer] transfer 0x563230a5b760
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=3 status=0 transferred=8
libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
libusb: debug [handle_bulk_completion] last URB in transfer --> complete!
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x563230a5b760 has callback 0x7f2537dfbb30
libusb: debug [sync_transfer_cb] actual_length=8
libusb: debug [libusb_free_transfer] transfer 0x563230a5b760
libusb: debug [libusb_release_interface] interface 0
libusb: debug [libusb_close]
libusb: debug [usbi_remove_pollfd] remove fd 26
libusb: debug [libusb_exit]
libusb: debug [libusb_exit] destroying default context
libusb: debug [libusb_get_device_list]
libusb: debug [discovered_devs_append] need to increase capacity
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_open] open 2.17
libusb: debug [usbi_add_pollfd] add fd 26 events 4
libusb: debug [libusb_kernel_driver_active] interface 0
libusb: debug [libusb_claim_interface] interface 0
Trying endpoint 129.
libusb: debug [libusb_alloc_transfer] transfer 0x563230a35450
libusb: debug [libusb_submit_transfer] transfer 0x563230a35450
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
Master Read Error! Rc: -1 Actual transfered bytes: 0.
Error code means: LIBUSB_ERROR_IO
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=3 status=-71 transferred=0
libusb: debug [handle_bulk_completion] handling completion status -71 of bulk urb 1/1
libusb: debug [handle_bulk_completion] low level error -71
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x563230a35450 has callback 0x7f2537dfbb30
libusb: debug [sync_transfer_cb] actual_length=0
libusb: debug [libusb_free_transfer] transfer 0x563230a35450
libusb: debug [libusb_release_interface] interface 0
libusb: debug [libusb_close]
libusb: debug [usbi_remove_pollfd] remove fd 26
libusb: debug [libusb_exit]
libusb: debug [libusb_exit] destroying default context

谢谢, 阿穆利亚

Thanks in advance. I am having 2 USB devices (master and slave). I am able to write data from master to slave but not able to read data from slave to master USB device I am getting   "LIBUSB_ERROR_IO" Error. The code has complete root access. The below is the code and output. The same code works fine in RHEL OS but not in Ubuntu. Code is in c++, tool Qt creator.

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <libusb-1.0/libusb.h>

#define EP_DATA_IN 0x81
#define EP_DATA_OUT 0x01
#define DEVICE_CONFIGURATION 0
#define MASTER 0x00f4
#define SLAVE 0x00f2

void writeButtonClicked()
{
int rc;
libusb_context *ctx = NULL;
libusb_device_handle *dev_handle;

QString writeData = "Slave writing !!!";
int actual = writeData.length();
unsigned char *sendData;

sendData = (unsigned char *)malloc(actual);
memcpy(sendData, writeData.toLocal8Bit(), actual);

rc = libusb_init(&ctx);
if(rc < 0) {
std::cout << "Init Error " << rc << std::endl;
}

libusb_set_debug(ctx, 6);


dev_handle = libusb_open_device_with_vid_pid(ctx, 0x04b4, SLAVE); // Give SLAVE or MASTER to perform write operation
if (!dev_handle) {
fprintf(stderr, "Error finding USB device\n");
}

if(libusb_kernel_driver_active(dev_handle, DEVICE_CONFIGURATION) == 1) {
std::cout << "Kernel Driver Active" << std::endl;
if(libusb_detach_kernel_driver(dev_handle, DEVICE_CONFIGURATION) == 0)
std::cout << "Kernel Driver Detached!" << std::endl;
}

rc = libusb_claim_interface(dev_handle, DEVICE_CONFIGURATION);
if(rc != 0) {
std::cout << "Cannot Claim Interface" << std::endl;
rc = libusb_set_interface_alt_setting(dev_handle, DEVICE_CONFIGURATION, 1);
if(rc!=0)
{
std::cout <<"Cannot configure alt setting "<<std::endl;
}
else
{
std::cout <<"configured alt setting "<<std::endl;
}
}

std::cout << "Data->" << sendData << "<-" << std::endl;
std::cout << "Writing Data..." << std::endl;

std::cout << "Trying endpoint " << EP_DATA_OUT << "." << std::endl;
rc = libusb_bulk_transfer(dev_handle, EP_DATA_OUT, sendData, sizeof(sendData), &actual, 1000);

if(rc == 0)
{
std::cout << "Writing Successful!" << std::endl;
}
else
{
std::cout << "Write Error! Rc: " << rc << " Actual transfered bytes: " << actual << "." << std::endl;
std::cout << "Error code means: " << libusb_error_name(rc) << std::endl;
}

rc = libusb_release_interface(dev_handle, 0);
if(rc!=0) {
std::cout << "Cannot Release Interface" << std::endl;
}

if (dev_handle)
libusb_close(dev_handle);

libusb_exit(ctx);
}

void readButtonClicked()
{
int rc;
libusb_context *ctx = NULL;
libusb_device_handle *dev_handle;

int actual = 0;
unsigned char *readData = new unsigned char[512];

rc = libusb_init(&ctx);
if(rc < 0) {
std::cout << "Init Error " << rc << std::endl;
}

libusb_set_debug(ctx, 6);

dev_handle = libusb_open_device_with_vid_pid(ctx, 0x04b4, MASTER); // Give SLAVE or MASTER to perform Read operation
if (!dev_handle) {
fprintf(stderr, "Error finding USB device\n");
}

if(libusb_kernel_driver_active(dev_handle, DEVICE_CONFIGURATION) == 1) {
std::cout << "Kernel Driver Active" << std::endl;
if(libusb_detach_kernel_driver(dev_handle, DEVICE_CONFIGURATION) == 0)
std::cout << "Kernel Driver Detached!" << std::endl;
}

rc = libusb_claim_interface(dev_handle, DEVICE_CONFIGURATION);
if(rc != 0) {
std::cout << "Cannot Claim Interface" << std::endl;
rc = libusb_set_interface_alt_setting(dev_handle, DEVICE_CONFIGURATION, 1);
if(rc!=0)
{
std::cout <<"Cannot configure alt setting "<<std::endl;
}
else
{
std::cout <<"configured alt setting "<<std::endl;
}
}

std::cout << "Trying endpoint " << EP_DATA_IN << "." << std::endl;
rc = libusb_bulk_transfer(dev_handle, EP_DATA_IN, readData, sizeof(readData), &actual, 1000);

if(rc >=0)
{
std::cout << "Read Success! Rc: " << libusb_error_name(rc) << " Actual transfered bytes: " << actual << "." << std::endl;
}
else
{
std::cout << "Read Error! Rc: " << rc << " Actual transfered bytes: " << actual << "." << std::endl;
std::cout << "Error code means: " << libusb_error_name(rc) << std::endl;
}

rc = libusb_release_interface(dev_handle, 0);
if(rc!=0) {
std::cout << "Cannot Release Interface" << std::endl;
}

if (dev_handle)
libusb_close(dev_handle);

libusb_exit(ctx);
}

//Output  Slave writing Master reading
libusb: debug [libusb_get_device_list]
libusb: debug [discovered_devs_append] need to increase capacity
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_open] open 2.16
libusb: debug [usbi_add_pollfd] add fd 26 events 4
libusb: debug [libusb_kernel_driver_active] interface 0
libusb: debug [libusb_claim_interface] interface 0
Data->Slave writing !!!<-
Writing Data...
Trying endpoint 1.
Writing Successful!
libusb: debug [libusb_alloc_transfer] transfer 0x563230a5b760
libusb: debug [libusb_submit_transfer] transfer 0x563230a5b760
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=3 status=0 transferred=8
libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
libusb: debug [handle_bulk_completion] last URB in transfer --> complete!
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x563230a5b760 has callback 0x7f2537dfbb30
libusb: debug [sync_transfer_cb] actual_length=8
libusb: debug [libusb_free_transfer] transfer 0x563230a5b760
libusb: debug [libusb_release_interface] interface 0
libusb: debug [libusb_close]
libusb: debug [usbi_remove_pollfd] remove fd 26
libusb: debug [libusb_exit]
libusb: debug [libusb_exit] destroying default context
libusb: debug [libusb_get_device_list]
libusb: debug [discovered_devs_append] need to increase capacity
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_open] open 2.17
libusb: debug [usbi_add_pollfd] add fd 26 events 4
libusb: debug [libusb_kernel_driver_active] interface 0
libusb: debug [libusb_claim_interface] interface 0
Trying endpoint 129.
libusb: debug [libusb_alloc_transfer] transfer 0x563230a35450
libusb: debug [libusb_submit_transfer] transfer 0x563230a35450
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
Master Read Error! Rc: -1 Actual transfered bytes: 0.
Error code means: LIBUSB_ERROR_IO
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=3 status=-71 transferred=0
libusb: debug [handle_bulk_completion] handling completion status -71 of bulk urb 1/1
libusb: debug [handle_bulk_completion] low level error -71
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x563230a35450 has callback 0x7f2537dfbb30
libusb: debug [sync_transfer_cb] actual_length=0
libusb: debug [libusb_free_transfer] transfer 0x563230a35450
libusb: debug [libusb_release_interface] interface 0
libusb: debug [libusb_close]
libusb: debug [usbi_remove_pollfd] remove fd 26
libusb: debug [libusb_exit]
libusb: debug [libusb_exit] destroying default context

Thanks,
Amulya

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌面超妹 2025-01-18 09:46:42

我在 Linux 上看到了只读的 LIBUSB_ERROR_IO,但在 Windows 上却没有看到完全相同的代码。

我的问题的根本原因是我试图对批量传输消息进行部分读取。例如,如果整个消息为 14 个字节,我尝试在单独的 libusb_bulk_transfer() 调用中读取 10 个字节,然后读取 4 个字节。

将我的代码更改为单个 14 字节 libusb_bulk_transfer() 读取现在可以在两个平台上正常工作。

我相信这在 Windows 上有效的事实是 UB 基于 LibUSB 的文档 - https: //libusb.sourceforge.io/api-1.0/libusb_packetoverflow.html

I saw a LIBUSB_ERROR_IO on read only on Linux, but not Windows for the exact same code.

The root cause of my issues was that I was trying to do partial reads of bulk transfer messages. For example, if the whole message was 14 bytes I was trying to read 10 bytes then 4 bytes in separate libusb_bulk_transfer() calls.

Changing my code to a single 14 byte libusb_bulk_transfer() read now works properly on both platforms.

I believe the fact that this worked on Windows was UB based on this documentation from LibUSB - https://libusb.sourceforge.io/api-1.0/libusb_packetoverflow.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文