记一次libusb库函数“libusb_bulk_transfer”的调用关系追踪
一次使用libusb库函数“libusb_bulk_transfer”对外部USB设备进行读取数据的时候,出现了无数据返回的情况,但是使用USB分析仪,看到USB总线是进行了一次完整的IN令牌的transfer,如下图,感觉像是中间某一个节点没有将收到的device数据包返回上来,所以对代码进行下追踪,定位下问题大致位置。

这里记录下追踪到的函数调用关系:
libusb库内部调用关系
先看下大致调用流程:
> libusb_bulk_transfer(sync.c)
----> do_sync_bulk_transfer(sync.c)
--------> libusb_submit_transfer(io.c)
------------> usbi_backend->submit_transfer(core.c)
------------> linux_usbfs_backend.submit_transfer(linux_usbfs.c)
------------> op_submit_transfer(linux_usbfs.c)
----------------> submit_bulk_transfer(linux_usbfs.c)
--------------------> ioctl
可以看到,最终实际是调用到了系统的“ioctl”函数。
简单分析一下:
- do_sync_bulk_transfer(sync.c)中有两个重要的函数,如下:
static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length,
int *transferred, unsigned int timeout, unsigned char type)
{
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
//这个函数用来填充一个用于bulk传输的struct libusb_transfer
libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
bulk_transfer_cb, &completed, timeout);
transfer->type = type;
//这里提交上面填充好的transfer
r = libusb_submit_transfer(transfer);
if (r < 0) {
libusb_free_transfer(transfer);
return r;
}
......
libusb_free_transfer(transfer);
return r;
}
- libusb_submit_transfer(io.c)会调用不同平台的usbi_backend->submit_transfer,如下:
int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
{
struct libusb_context *ctx = TRANSFER_CTX(transfer);
struct usbi_transfer *itransfer =
LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
int r;
int first;
......
first = add_to_flying_list(itransfer);
//根据编译平台的不同,调用对应平台的 struct usbi_os_backend 成员 submit_transfer
r = usbi_backend->submit_transfer(itransfer);
if (r) {
usbi_mutex_lock(&ctx->flying_transfers_lock);
list_del(&itransfer->list);
usbi_mutex_unlock(&ctx->flying_transfers_lock);
}
......
out:
usbi_mutex_unlock(&itransfer->lock);
return r;
}
不同平台的区分在core.c文件,如下:
#if defined(OS_LINUX)

本文详细追踪了在使用libusb库函数libusb_bulk_transfer从USB设备读取数据时遇到的问题,涉及libusb库内部调用、USB设备文件节点、驱动层和HCD的交互,最终定位到硬件获取数据失败。
最低0.47元/天 解锁文章
663

被折叠的 条评论
为什么被折叠?



