连续读取传入数据(usb4java)

时间:2014-05-06 11:48:45

标签: java usb libusb-1.0 libusb-win32 usb4java

我花了相当多的时间试图找出使用usb4java(Libusb)的低级函数连续读取大量数据的最佳方法。

在全速设备中,我需要读取的数据量是640kbyte / s,理论上是可行的,我应该使用不到一半的可用带宽。我遇到的问题是我正在阅读的数据有可能来自丢失或损坏数据的故障。

我尝试过同步和异步同样的结果。在这里,我发布了我在异步模式下使用的代码,感谢任何帮助。

public Void doInBackground() {

    loop = true;
    handle = comm_device_async.gethandle();

    buffer = BufferUtils.allocateByteBuffer(PacketSize).order(ByteOrder.LITTLE_ENDIAN);
    Transfer transfer = LibUsb.allocTransfer();

    LibUsb.fillBulkTransfer(transfer, handle, IN_ENDPOINT, buffer, read_callback, null, TIMEOUT);
    int result = LibUsb.submitTransfer(transfer);
    if (result != LibUsb.SUCCESS) {
        throw new LibUsbException("Unable to submit transfer", result);
    }

    while (loop) {
        synchronized (synchObj) {
            while (!transfercompleted) {
                try {
                    synchObj.wait();
                } catch (InterruptedException ex) {
                    Logger.getLogger(GraphPanel_JChart2D.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        transfercompleted = false;

        multipledatashort[readcyclecount] = read_callback_data;
        readcyclecount++;
        if (readcyclecount == readcycles) {
            synchronized (dataListShort) {
                dataListShort.add(multipledatashort);
                dataListShort.notify();
            }
            readcyclecount = 0;
        }

    }
    return null;
}

TransferCallback read_callback = new TransferCallback() {

    ByteBuffer buffer;
    long startTime = 0;

    @Override
    public void processTransfer(Transfer transfer) {
        System.out.println("ReadCallback loop time " + (System.nanoTime() / 1000 - startTime));
        startTime = System.nanoTime() / 1000;
        read_callback_data = new short[transfer.buffer().capacity() / 2];
        for (int i = 0; i < read_callback_data.length; i++)
            read_callback_data[i] = transfer.buffer().getShort();


        synchronized (synchObj) {
            transfercompleted = true;
            synchObj.notify();
        }

        buffer = BufferUtils.allocateByteBuffer(PacketSize).order(
                ByteOrder.LITTLE_ENDIAN);
        LibUsb.fillBulkTransfer(transfer, collectWorker_usb4java_async_fast.handle, IN_ENDPOINT, buffer,
                read_callback, null, TIMEOUT);
        int result = LibUsb.submitTransfer(transfer);
        if (result != LibUsb.SUCCESS) {
            throw new LibUsbException("Unable to submit transfer", result);
        }

    }
};

1 个答案:

答案 0 :(得分:0)

我发现了一个描述相似问题的线程

http://libusb.6.n5.nabble.com/Fwd-FT2232H-asynchronous-maximum-data-rates-td4519549.html

有两个要点

  1.   

    他说要异步提交一个请求(和   重新提交它)比提交同步更糟糕   要求。这是预期的,做更多繁忙的工作需要更多的时间。

  2.   

    目标是保持内核的URB列表不断填充。   无论何时该列表清空,都有可能无法重新填充   请求数据的时间和FT2232H缓冲区将填满。所以   正确执行异步模式的方法是制作传输列表。每当其中一个返回时,另一个请求。   将此请求转换为该请求所涉及的开销   相应的URB列表,但只要列表开始大   足够的,我们可以在另一个时间内分摊这个开销   转移需要完成

  3. 所以基本上对于大量数据我们需要提交一个事务缓冲区,所以当最后一个结束时总会有一个待处理。

    我将继续努力,但我还没有找到使用usb4java如何做到这一点的好例子。再次,任何帮助表示赞赏