USB调试笔记
+ -

批量传输:自定义接口实现

2022-05-04 1060 12
[TOC]

在进行 usb 传输的过程中,往往需要大容量传输。无外乎批量传输。典型的批量传输协议如下:

cdc-acm :usb 转串口。win10 以下需要 pc 驱动。
massstroage:U 盘设备。

通常仅仅只需要批量传输,而不想引入复杂的协议,这个时候自定义接口进行批量传输就比较合适了,需要注意的是自定义接口需要安装pc驱动, host 并不支持自定义的接口。

1. 描述符布局

233105208975

Inerface Descriptor
Endpoint Descruptor(in)
Endpoint Descruptor(out)

2. 描述符介绍

这里只介绍接口描述符端点描述符,并且是独立的接口设备。

自定义接口:关联两个端点

static struct usb_interface_descriptor intf_desc = {
        .bLength                = sizeof(intf_desc),
        .bDescriptorType        = USB_DT_INTERFACE,
        .bNumEndpoints          = 0x02,
        .bInterfaceClass        = 0xFF,
        .bInterfaceSubClass     = 0x0,
        .bInterfaceProtocol     = 0x0,
};

端点描述符:in/out 端点

static struct usb_endpoint_descriptor hs_bulk_in_desc = {
        .bLength                = USB_DT_ENDPOINT_SIZE,
        .bDescriptorType        = USB_DT_ENDPOINT,
        .bEndpointAddress       = USB_DIR_IN,
        .bmAttributes           = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize         = cpu_to_le16(512),
};

static struct usb_endpoint_descriptor hs_bulk_out_desc = {
        .bLength                = USB_DT_ENDPOINT_SIZE,
        .bDescriptorType        = USB_DT_ENDPOINT,
        .bEndpointAddress       = USB_DIR_OUT,
        .bmAttributes           = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize         = cpu_to_le16(512),
};

整体接口描述符

static struct usb_descriptor_header *hs_intf_descs[] = {
        //(struct usb_descriptor_header *) &iad_desc,
        (struct usb_descriptor_header *) &intf_desc,
        (struct usb_descriptor_header *) &hs_bulk_out_desc,
        (struct usb_descriptor_header *) &hs_bulk_in_desc,
        NULL,
};

接口描述符如下:

233143945806

3. 复合设备

有的时候我们需要在已有的设备功能上,添加一个接口自定义功能。这个时候就需要添加复合设备。复合设备独立接口设备唯一区别在于接口描述符和设备描述符符不同。

233219431771

  • 自定义接口,添加一个iad 关联
IAD Descriptor
Inerface Descriptor
Endpoint Descruptor(in)
Endpoint Descruptor(out)

IAD 描述符:

static struct usb_interface_assoc_descriptor iad_desc = {
        .bLength                = sizeof(iad_desc),
        .bDescriptorType        = USB_DT_INTERFACE_ASSOCIATION,
        .bFirstInterface        = 0,  // 动态修改
        .bInterfaceCount        = 1,
        .bFunctionClass         = 0xFF, // vendor
        .bFunctionSubClass      = 0x00,
        .bFunctionProtocol      = 0x00,
        .iFunction              = 0,
};

整体接口描述符:

static struct usb_descriptor_header *hs_intf_descs[] = {
        (struct usb_descriptor_header *) &iad_desc,
        (struct usb_descriptor_header *) &intf_desc,
        (struct usb_descriptor_header *) &hs_bulk_out_desc,
        (struct usb_descriptor_header *) &hs_bulk_in_desc,
        NULL,
};

自定义接口描述符如下:
233314818779

4. 驱动适配

对于自定义接口,需要按照pc 驱动,否则 windows 端无法识别。

使用 zadig-2.5.exe 按照对应接口的设备驱动。这里是接口2

233338379873

不同的驱动对应不同的系统调用。
winUSB:对应 libusb(1.0) 系统调用
libusbK:对应libusbK 系统调用
libusb-win32:对应libusb-0.1(libusb-win32) 系统调用

有关libusb、libusbK、libusb-win32 之间的关系本文不做过多介绍,这里只是版本的差异。

5. 主机应用

以libusb 为例介绍。

5.1 控制传输

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

控制写:

  ...
  libusb_device_handle* handle = dev->handle;    
  int status = libusb_control_transfer(
        handle,
        /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE,
        /* bRequest      */ bRequest,
        /* wValue        */ 0,
        /* wIndex        */ 0,
        /* Data          */ (unsigned char *)data,
        /* wLength       */ len,
        ms);

控制读:

...
   libusb_device_handle* handle = dev->handle;
   int status = libusb_control_transfer(
            handle,
            /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE,
            /* bRequest      */ bRequest,
            /* wValue        */ 0,
            /* wIndex        */ 0,
            /* Data          */ (unsigned char*)(*data),
            /* wLength       */ len,
            ms);
    return status;

5.2 批量传输

int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,
    unsigned char endpoint, unsigned char *data, int length,
    int *actual_length, unsigned int timeout);

批量读:

int bulk_read(struct bulkusbdev* dev, void* buffer, size_t len, int ms)
{
    int size, errcode;
    libusb_device_handle* handle = dev->handle;
    uint8_t endpoint_in = dev->endpoint_in;

    errcode = libusb_bulk_transfer(handle, endpoint_in,(unsigned char*) buffer, len, &size, ms);
    if (errcode < 0)
    {
        printf("read:   %s\n", libusb_strerror((enum libusb_error)errcode));
        return -1;
    }

    return size;
}

批量写:

int bulk_write(struct bulkusbdev* dev, void* buffer, int len, int ms)
{
    int size, errcode;
    libusb_device_handle* handle = dev->handle;
    uint8_t endpoint_out = dev->endpoint_out;

    errcode = libusb_bulk_transfer(handle, endpoint_out, (unsigned char*)buffer, len, &size, ms);
    if (errcode<0)
    {
        printf("write:   %s\n", libusb_strerror((enum libusb_error)errcode));
        return -1;
    }

    return size;
}

6. 总结

本文简单介绍了,USB 设备自定义批量传输的设备描述符实现,有关不同的平台,设备驱动实现方式不一。掌握了描述符,基本就掌握了设备实现的核心。参考对应平台做相关移植即可。

注释:有关windows 驱动仅学习使用,商用可能需要做数字签名

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

USB传输过程中的延迟
USB传输过程中的延迟可分为包间延迟、USB线缆上的延迟和USB集线器延迟。在数据传输时,USB主机和USB设备能够计算整个数据传输时间,这个数据传输的时间由发送方发数据信息包结束时开始计算,直到接收到接收方的应答信号为止。USB包间延迟USB数据传输的包间延迟只存在于一个USB数据流管理中的各......
UVC 等时传输中的URB_ISOCH_TRANSFER
通过UVC规范可知,视频图像数据的读取可使用两种端点传输方式,分别为:BULK 块/批量传输方式ISO 等时/同步传输方式在Windows内核中,USB数据的读取是通过URB来进行传输的,其结构体是一个大大的共用体,根据数据传输的方式对应其不同的结构体,其内容如下:typedef _Struct_s......
USB设备和USB集线器HUB的数据传输
USB高速集线器与USB根集线器之间只通过USB使用USB高速通讯讯方式,而对于低速或全速的数据通讯的转换是由其挂接的最近的USB-HUB负责完成转换。如下图:对于USB高速设备和USB高速HUB,使用高速通讯。对于连接到高速HUB上的低速或全速USB-HUB,使用低速或全速通讯方式。对于连接到高速......
USB4的连接接口、传输速度的兼容性
官方称为USB4.0,USB4即将上市。一些规格仍有待确认,这里是一个快速概述一切,我们知道最新的USB标准。USB4会向后兼容USB3.0,USB2.0,USB1.0吗?USB4电缆将使用TYPE-C连接器,这是目前大多数智能手机和笔记本电脑上的扁平圆形端口。我们看到许多工业小型单板计算机都......
USB 中断传输方式
USB协议规定了四种传输类型:控制传输、批量传输、同步传输、中断传输。中断传输一般用于小批量的和非连续的数据传输,通俗的来说就是用于数据量小的数据不连续的但实时性高的场合的一种传输方式,主要应用于人机交互设备(HID)中的USB鼠标和USB键盘等。USB中断传输和我们传统意义上的中断不一样。......
USB存储设备在Windows环境下使用Uaspstor.sys或Usbstor.sys那个驱动?
USB Attached SCSI (UAS) 协议是一种新的大容量存储协议,旨在通过已建立的 USB 大容量存储协议(仅批量传输)和 BOT (提高性能) 。 它通过减少协议开销、支持 SATA 本机命令队列 (NCQ) 并并行处理多个命令。 为此,UAS 使用新的 USB 3.0 功能进行称为流......
UVC摄像头批量传输的StreamOn和StreamOff
在UVC规范中,UVC摄像头视频数据的传输方式支持两种,分别为批量传输和同步传输。UVC摄像头数据传输的格式按负载数据头的方式按帧进行打包传输。根据USB规范可知,同步传输方式是只要带中带有同步端点的接口,系统会定时从设备中读取数据,无论设备中是否有数据。而如要要停止数据的传输,只需要选中不带有同步......
UVC等时传输中的dwMaxPayloadTransferSize
UVC的视频流接口控制请求的数据大小可为26字节,34字节和48字节,其分别对应的是UVC的1.0,1,1和UVC1.5版本。在其整个视频流控制接口参数偏移地址22处的字段为一4字节的dwMaxPayloadTransferSize,根据其字段解释为“指定设备在单个有效负载传输中可以传输或接收的最大......
USB是什么,USB的优点、设备分类及传输方式有那些?
USB是由世界著名计算机和通信公司等共同推出的新一代接口标准,全称为Universal Serial Bus(通用串行总线),是一种快速、灵活的总线接口。它是为了解决日益增加的PC外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准。USB一般分为USB低速,USB全速,USB高速和USB......
USB超高速 中断传输
中断传输类型用来支持带有轮询服务间隔需要高可靠性传输小数量数据的设备。这个规格的协议层章详细描述了与中断传输相关的包,总线事务和事务处理流程。超速中断传输类型一般提供以下方面:能保证最大的服务间隔能保证在下一次服务间隔中尝试重新传输在每个服务周期中为中断端点尝试中断传输,保留一定带宽保证在每个服务间......
BOT传输协议和UASP传输协议有什么区别?
BOT传输协议BOT (Bulk-Only Transport),诞生于1999年,专为USB 1.1所设计,至今最快的USB 3.1都可向下兼容这个基本的BOT传输协议。在传输资料作业开始时,外接USB 3.0设备与电脑主板(USB 3.0扩展卡)之间,在同一时间单位内,每次只传输单一指令,所以速......
USB 控制传输方式
USB协议规定了四种传输类型:控制传输、批量传输、同步传输、中断传输。控制传输是一种特殊的传输方式。当USB设备初次连接主机时,用控制传输传送控制命令等对设备进行配置。同时设备接入主机时,需要通过控制传输去获取USB设备的描述符以及对设备进行识别,在设备的枚举过程中都是使用控制传输进行数据交换......
UVC等时传输中的dwMaxVideoFrameSize和dwMaxPayloadTransferSize关系
在其整个视频流控制接口参数偏移地址18处的字段为一4字节的dwMaxVideoFrameSize,代表的是如果选择当前数据帧格式,其一帧图像的最大数据量大小,以字节为单位。关于dwMaxVideoFrameSize的计算可以参考 YUV2摄像头相关数据大小计算。这里我们主要说一下dwMaxVideo......
DirectShow数据传输协议
DirectShow数据传输协议定义为了进行数据交换,DirectShow的过滤器(filter)必须支持相关的数据传输协议,这个传输的协议叫做transports。当2个图形过滤器的pin相连接后,它们必须支持相同的transports,除非它们进行数据交换。通常,传输要求其中一个管脚支持特定接口......
UVC批量传输中的dwMaxVideoFrameSize和dwMaxPayloadTransferSize关系
上一节看了UVC等时/同步传输的关系,这里我们介绍一相批量传输。批量传输在这里相对于同步传输要简单的多。uvc_video_start_transfer中的代码如下: else { /* Bulk endpoint, proceed to URB initialization. */ ......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!