libusb使用详解六(USB设备的数据传输之同步模式)

Linux libusb USB开发(四)—— libusb例程,Linux环境下实现PC与USB设备的交互通信 (用的QT C++) 一、具体流程 用libusb函数库来完成电脑与USB设备的数据交互功能,主要有以下步骤: 1)初始化libusb函数库; 2)根据vid和pid查找某一具体设备,并获取设备描述符;(vid和pid为设备的id,且每台设备的都vid和pid是唯一的) 3)根据设备描述符打开相应设备,获取设备操作符; 4)用设备操作符配置usb设备的配置模式和接口; 5)调用相应传输函数向usb设备发送数... 阅读详情
AI摘要

本文介绍了USB设备的四种传输方式:控制、中断、批量和实时传输。阐述了libusb 1.0 API传输函数特点,即不分读写用相同函数,区别在Request type或端口地址。还说明了各传输方式用途、实现函数及参数,如控制传输用libusb_control_transfer,实时传输同步模式无对应函数。

USB设备的传输方式主要有四种:控制传输(Control Transfer)、中断传输(Interrupt Transfer)、批量传输(Bulk Transfer)和实时传输(Isochronous Transfer)。

具体内容可以参考https://blog.youkuaiyun.com/ljr1433223/article/details/130049625

libusb 1.0 API中的数据传输接口都是双向的,也就是说不分读写都是使用相同的函数。唯一的区别在于Request type或者端口地址。当它的最高位是0,就表示这次传输的是主机到设备的,主机角度来说就是写操作;反之是1的话就是设备到主机的,主机角度来说就是读操作。这是libusb 1.0 API传输函数的特点。

1. 控制传输(Control Transfer)

控制传输是USB必备的传输方式,它用于传输Control Setup包。它一般用于获取设备信息、状态,选择设备配置等的一系列命令式工作。关于Control Setup包的定义,可参考https://blog.youkuaiyun.com/wdsfup/article/details/49945205。

因为libusb API已经实现了一套获取USB设备信息的接口(具体可查看前面“ USB设备的基本操作”这一节),所以一般我们不用直接实现控制传输。只有在实现特定设备的特定控制命令时,比如获取PS3、XBOX主机的基本信息,才会需要自己实现控制传输。

libusb使用函数libusb_control_transfer来实现控制传输。函数定义如下:

int libusb_control_transfer (
    libusb_device_handle *dev_handle,
    uint8_t bmRequestType,
    uint8_t bRequest,
    uint16_t wValue,
    uint16_t wIndex,
    unsigned char *data,
    uint16_t wLength,
    unsigned int timeout)

其中:
dev_handle:为上一节“USB设备的打开与关闭”中介绍的获取的USB设备句柄,后续不再赘述
bmRequestType: 为Control Setup包的request type部分。libusb有预定义了枚举类型来表示其中的传输方向,设备种类和接受者。传输方向可以用libusb_endpoint_direction类型,设备种类可以使用libusb_request_type类型,接受者可以使用libusb_request_recipient。所以,如果想要构建Get_Configuration命令的Request type,可以使用LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE这一组合
bRequest: 为Control Setup包的request命令。可以使用libusb_standard_request类型表示。比如:Get_Configuration命令可用LIBUSB_REQUEST_GET_CONFIGURATION
wValue: 为Control Setup包的value部分,该值需要根据Request命令设定相应的值,可以参考参考链接中的相关内容进行设定。
wIndex: 为Control Setup包的index部分,设置方式和wValue类似
data:为额外数据的buffer指针,比如设置和获取的Descriptor的字符串数据。
wLength:为额外数据buffer的最大长度。
timeout: 为发送此命令的超时时间,单位为ms。永远等待设成0即可。超时发生时,函数返回LIBUSB_ERROR_TIMEOUT错误
返回值:成功时返回传输数据的实际长度,一般大于0。失败时返回小于0的LIBUSB_ERROR_XXX错误码

例程如下,例程中实现了接口libusb_get_configuration的相同功能

bool GetConfigurationManual() {
    if (mDevHandle == nullptr) {
        LOGE("Failed to transfer control packet as device isn't initialized properly");
        return false;
    }
    u8 data[256] = {0};
    int ret = libusb_control_transfer(mDevHandle,
        LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
        LIBUSB_REQUEST_GET_CONFIGURATION, 
        0, 0, data, sizeof(data), 100);
    if (ret < 0) {
        LOGE("Failed to transfer control packet, error: %d", ret);
        return false;
    }
    LOGD("Got Configuration data: %s", bufferToString(data, (size_t)ret).c_str());
    return true;
}
2. 中断传输(Interrupt Transfer)

中断传输采用轮询的方式进行数据的收发。它一般用于单次传输数据量较少,但数据传输频次较多的环境。它的传输优先级比较高,时效性比较好。所以,鼠标和键盘信号的传输方式就是中断传输。

libusb使用函数libusb_interrupt_transfer来实现中断传输。函数定义如下:

int libusb_interrupt_transfer (
    libusb_device_handle *dev_handle,
    unsigned char endpoint,
    unsigned char *data,
    int length,
    int *transferred,
    unsigned int timeout)

其中:
endpoint:为端口地址,可以通过在“USB设备的基本操作”一节中描述的获取USB Configuration信息的方式来获取。它就是endpoint->bEndpointAddress的值。当然如果根据产品Spec知道其Address,也可以直接设置。该值的最高位为0表明它是只写端口,为1表示它是只读端口
data: 为待发送或接收数据的buffer指针
length:为待发送或接收数据的buffer的最大长度
transferred:表示实际发送或接收数据的长度
timeout: 表示传输数据的超时时间,单位为ms。永远等待设成0即可。超时发生时,函数返回LIBUSB_ERROR_TIMEOUT错误
返回值:成功时返回LIBUSB_SUCCESS,否则返回小于0的LIBUSB_EEROR_XXX错误码

注意:不管发送还是接收,数据buffer的长度必须等于endpoint->wMaxPacketSize所规定的最大长度

例程如下:

int InterruptTransPkt(u8 ep, u8* buffer, int length, u32 timeout) {
    if (mDevHandle == nullptr) {
        LOGE("Failed to transfer packet as device isn't initialized properly");
        return LIBUSB_ERROR_OTHER;
    }

    int actualLength = 0;
    int ret = libusb_interrupt_transfer(mDevHandle, ep, buffer, length, &actualLength, timeout);
    if (ret != LIBUSB_SUCCESS) {
        if (ret == LIBUSB_ERROR_TIMEOUT && actualLength > 0) {
            return actualLength;
        }
        LOGE("Failed to transfer package, error: %d", ret);
        return ret;
    }
    return actualLength;
}
3.  批量传输(Bulk Transfer)

批量传输主要应用在单次传输大量数据的时候,它的时效性较差,主要用于对延时不敏感的情况。比如:U盘数据的传输就是批量传输。

libusb使用函数libusb_bulk_transfer来实现批量传输。函数定义如下:

int libusb_bulk_transfer (
    libusb_device_handle *dev_handle,
    unsigned char endpoint,
    unsigned char *data,
    int length,
    int *transferred,
    unsigned int timeout)

它的参数和中断传输函数类似,其中:
endpoint:为端口地址,获取方式类似中断传输
data: 为待发送或接收数据的buffer指针。buffer大小同样也需要设定为endpoint->wMaxPacketSize所规定的最大长度
length:为待发送或接收数据的buffer的最大长度
transferred:表示实际发送或接收数据的长度
timeout: 表示传输数据的超时时间,单位为ms。永远等待设成0即可。超时发生时,函数返回LIBUSB_ERROR_TIMEOUT错误
返回值:成功时返回LIBUSB_SUCCESS,否则返回小于0的LIBUSB_EEROR_XXX错误码

因为批量传输函数和中断传输函数类似,例程可参考中断传输的例子。

4.  实时传输(Isochronous Transfer)

不同于上述三种传输方式,实时传输并不保证传输数据的准确性,有点类似网络传输的UDP传输。但是它具有最好的时效性,所以通常用于传输摄像头捕获的视频或者给音响传输音频数据。

因为实时传输需要进行异步操作,所以libusb并没有提供同步模式下的函数。如果需要实现实时传输必须使用libusb数据传输的异步模式。这会在下一节详细描述。

USB系列-LibUSB使用指南(1)-Windows下的报错与踩坑 Windows下的LibUSB开发的大怨种踩坑日记 阅读详情

相关推荐

虚拟机Linux访问usb设备,通过Libusb库方法实现读写usb设备所获取的实时图像数据

一、前言基于Linux 平台USB驱动开发,主要有内核驱动的开发和libusb的无驱设计;首先为什么要选第三方库Libusb,可能是基于Libusb的程序只涉及到应用层,使用起来更加方便;如果是在内核驱动,就要考虑到内核大小、内核版本的兼容,如果客户需要把你的USB模块加入他们的平台,那岂不是还要重新根据客户要求裁剪、编写内核?又假如有许多客气,而且每个客气的平台不一样,那是不是需要为每个客户定制一

psy6653的博客 1万+

libusb 使用说明

Window下: 1.  下载地址:https://sourceforge.net/projects/libusb-win32/  下载libusb-win32-bin-1.2.6.0 2. 选择bin目录中的inf-wizard.exe;点Next;然后根据vid,pid指定一个usb设备;点Next,保存Inf文件,点Install Now;成功后可以在设备管理器中看到多了一个li

o1o恭喜发财o1o的专栏 7081

Linux libusb USB开发(六)—— 扩展:windows下libusb的使用例程 (用QT C++实现)

一、具体流程 与Linux环境下一样,用libusb函数库来完成电脑与USB设备的数据交互功能,主要有以下步骤: 1)初始化libusb函数库; 2)根据vid和pid查找某一具体设备,并获取设备描述符;(vid和pid为设备的id,且每台设备的都vid和pid是唯一的) 3)根据设备描述符打开相应设备,获取设备操作符; 4)用设备操作符配置usb设备的配置模式和接口; 5)调用相应传...

爱机械的假程序猿的博客 4087

libusb 收发数据函数libusb_bulk_transfer

上位机:android,usb编程用的是libusb 下位机:stm32,用的是板子自带的库 问题:在传输的过程中发现,上位机获取数据的时候会有数据丢失。 测试过程:     一:上位机与板子创立连接,发送控制命令,代表可通信。libusb_control_transfer(dev_handle, 0xA1, 0x21, 0, 0, NULL, 0, 0)。            解

8615

linux下使用libusb获取系统usb设备具体信息

libusb简介

VizXu的博客 2万+

在 QT 中使用 libusb 检测 MAC 上的 USB 设备

最近在用 QT 做一个 MAC 上的 Kindle 批注管理软件,遇到的第一个问题就是检测 MAC 上连接的 USB 设备的状态。如果是在 Cocoa 进行开发,会有对应的系统 API 可供使用,但是由于我是在 QT 平台进行的开发,所以无形中加大了一点难度。就在这时,我发现了一个库:libusb libusb 介绍libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以

远航 | FIBOS.io 8918

USB学习4-libusb的使用

libusb是一个使用C编写的库,它提供USB设备的通用的访问方法。APP通过它,可以方便地访问USB设备,无需编写USB设备驱动程序。可移植性:支持Linux、macOS、Windows、Android、OpenBSD等用户模式:APP不需要特权模式、也不需要提升自己的权限即可访问USB设备支持所有USB协议:从1.0到3.1都支持libusb支持所有的传输类型(控制/批量/中断/实时),有两类API接口:同步(Synchronous,简单),异步(Asynchronous,复杂但是更强大)

天使之翼 1万+

关于libusb开源库的使用

libusb是一个使用C编写的库,它提供USB设备的通用的访问方法。APP通过它,可以方便地访问USB设备,无需编写USB设备驱动程序。可移植性:支持Linux、macOS、Windows、Android、OpenBSD等用户模式:APP不需要特权模式、也不需要提升自己的权限即可访问USB设备支持所有USB协议:从1.0到3.1都支持libusb支持所有的传输类型(控制/批量/中断/实时),有两类API接口:同步(Synchronous,简单),异步(Asynchronous,复杂但是更强大)。

jia_weihui的博客 3639

libusb使用详解五(USB设备的打开与关闭)

描述使用libusb打开USB设备使其可以读写,以及使用后设备后正常关闭的过程

c12f20的专栏 1714

C 语言USB通信之使用 libusb库

要使用这些库和API,首先安装它们。安装完成后,需要阅读库和API的文档,了解如何使用它们与USB设备进行通信。这些文档通常会提供示例代码和API的使用方法。需要注意的是,与USB接口通信可能需要特定的权限和访问控制。在某些情况下,可能需要以管理员身份运行您的程序,或者在系统设置中配置特定的访问权限。在C语言中,要与USB接口通信,通常需要使用特定的库和API。在Windows上,需要确保安装libusb库及其开发文件。

A185822153的专栏 3774

如何在Linux下利用Libusb与HID USB设备通信!

由于公司的产品,导致我在Linux下写usb通信的代码出现了许多的问题,最后发现这些设备只能通过控制传输来操作设备,所以后面的问题就迎刃而解了。现在贴上当时在QT下写的代码,以防日后再碰到此类问题的时候翻查。 libusb_device **devs; libusb_device_handle *dev_handle; libusb_context *ctx=NULL;

a7082633的博客 1万+

探索 C++ 与 LibUSB:开启 USB 设备交互的奇幻之旅

C++ 与 LibUSB 的结合为开发者打开了一扇通往 USB 设备无限可能的大门。从基础的设备枚举、信息获取,到复杂的控制传输、批量与中断传输操作,再到高级的异步处理、多线程优化以及与其他库的融合,LibUSB 提供了全面而强大的工具集。

candy的博客 2691

libusb开发指南

libusb分析及使用指南

ARM-Linux 2万+

libusb使用详解三(USB设备的枚举和Hotplug)

介绍libusb API枚举USB设备和处理Hotplug事件的接口函数

c12f20的专栏 1628

libusb:libusb_bulk_transfer的timeout参数问题

timeout参数 1. bulk in:在指定的timeout参数时间内会一直阻塞等待接收,0为一直阻塞等待。 while(1) { rec = libusb_bulk_transfer(dev_handle, 0x81, rev_buf, 200, &amp;size, 0); if(rec == 0) { printf("rev sucess,length:%d ,data ...

ARM-Linux 9682

libusb 块传输 同步传输 例程

libusb 块传输 同步传输 例程,网上相关资源不多.

libusb使用详解七(USB设备的数据传输之异步模式)

介绍了使用libusb API如何实现USB设备的异步传输

c12f20的专栏 2251

【QEMU系统分析之TPM篇(一)】

本文以 QEMU 8.2.2 为例,分析其 TPM-emulator 模块的实现,并为 QEMU 添加 Windows 平台的TPM 模拟器的支持。

David唐辉的博客 1191

libusb使用详解四(USB设备的基本操作)

简单介绍libusb API如何获取USB设备的基本信息

c12f20的专栏 1662

NLP-Beginner 任务一:基于机器学习的文本分类(超详细!!)

NLP-Beginner 任务一:基于机器学习的文本分类传送门一. 介绍1.1 任务简介1.2 数据集1.3 流程介绍二. 特征提取2.1 词袋特征(Bag-of-word)2.2 N元特征 (N-gram)三. 最优化求解3.1 Softmax回归介绍3.2 损失函数3.3 梯度下降3.4 学习率四. 代码及实现4.1 实验设置4.2 结果展示4.3 代码新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、

0oTedo0 9935

打通Creo与Matlab的桥梁:Simscape Multibody Link插件安装与配置全攻略

本文详细介绍了Simscape Multibody Link插件的安装与配置全流程,旨在帮助机械工程师和开发者打通Creo与Matlab/Simulink之间的桥梁,实现CAD模型到多体动力学仿真的高效转换。文章重点解析了版本兼容性、管理员权限、注册文件配置等关键步骤与常见故障排查方法,助力用户快速建立设计与仿真一体化工作流。

rrr55的博客 634
上一篇: libusb使用详解五(USB设备的打开与关闭)
下一篇: libusb使用详解七(USB设备的数据传输之异步模式)
c12f20
博客等级 码龄19年 69粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值