首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连续读取输入数据(usb4java)

连续读取输入数据(usb4java)
EN

Stack Overflow用户
提问于 2014-05-06 11:48:44
回答 1查看 2.7K关注 0票数 1

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

在全速设备中,我需要读取的数据量是640千字节/秒,理论上是可能的,而且我使用的带宽应该少于可用带宽的一半。我遇到的问题是,我正在读的数据有一些小故障,可能来自丢失或损坏的数据。

我已经尝试过同步和异步的类似结果。在这里,我发布了我在异步模式下使用的代码,任何帮助都是非常感谢的。

代码语言:javascript
复制
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);
        }

    }
};
EN

回答 1

Stack Overflow用户

发布于 2014-05-07 14:59:04

我找到了一条描述类似问题的帖子

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

有两个要点

  1. 他说异步提交单个请求(并重新提交请求)比提交同步请求更糟糕。这是意料之中的,做更多的忙碌工作需要更多的时间。

  1. 其目标是使内核中的URB列表不断地被填满。每当列表清空时,就有可能不会及时重新填充请求数据,FT2232H缓冲区也会被填满。因此,异步模式的正确方法是列出一个传输列表。每次它们中的一个返回时,都会请求另一个。将此请求转换为相应的URBs列表涉及到开销,但只要列表开始足够大,我们就可以在完成其他传输所需的时间内摊销此开销。

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

我将致力于这方面的工作,但我还没有找到任何关于如何使用usb4java来完成这一工作的好例子。同样,任何帮助都是非常感谢的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23493915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档