usb4java源码分析

usb协议

可以简单认为host拥有一棵usb树,在这棵树上挂载usb节点。查询和连接指定的device时需要给出两个信息:

  • vendorId
  • productId

因此对于high-level api,有以下查找device的实现:

// 和递归查目录树是一样的
public UsbDevice findDevice(UsbHub hub, short vendorId, short productId)
{
   
    for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
    {
   
        UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
        if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
        if (device.isUsbHub())
        {
   
            device = findDevice((UsbHub) device, vendorId, productId);
            if (device != null) return device;
        }
    }
    return null;
}

操作流程

使用usb4java的通信流程如下:

graph TD
A[find device]
A-->B[claim iface]
B-->C{get endpoint}
C-->|UsbConst.OUT| D[outPipe]
C-->|UsbConst.IN| E[inPipe]
D-->F[open pipe]
E-->F[open pipe]
F-->G[syn- or asyn- submit byte data]
G-->H[close pipe]
H-->I[release iface]

上述endpoint之后分出in和out两种pipe,与usb的位定义有关。具体地,endpoint有一个字节的描述符,其中0:3位表示usb number;4:6位保留,第7位指示是发送还是接收。因此通过指定第7位的值(使用UsbConst)来获取in/out pipe。

如何收发字节数据

当pipe打开后,有两种方式收发数据:同步和异步submit。以下主要介绍异步submit是如何收发数据的。

首先submit需要传入一个byte数组:

byte[] data = new byte[1024];
inPipe.asyncSubmit(data);

该数组会被UsbIrp对象包装,然后塞到一个IrpQueue中。

final UsbIrp irp = createUsbIrp();
irp.setAcceptShortPacket(true);
irp.setData(data);
...
this.queue.add(irp);

队列检测到有包进入,启用一个线程处理:

public final void add(final T irp)
{
   
    this.irps.add(irp);

    // Start the queue processor if not already running.
    if (this.processor == null)
    {
   
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值