java - 读取连续传入的数据(usb4java)

标签 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);
        }

    }
};

最佳答案

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

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

主要有两点

  1. He is saying submitting a single request asynchronously (and resubmitting it) turns out to work worse than submitting synchronous requests. This is expected, doing more busywork takes more time.

  2. the goal is to keep the list of URB's at the kernel constantly filled. Anytime that list empties, there's a chance it won't be refilled in time to request data and the FT2232H buffer will fill up. So the right way to do the asynchronous mode is to make a list of transfers. Each time one of them returns, another is requested. There's overhead involved in converting this request into the corresponding list of URBs, but as long as the list starts out big enough, we can amortize this overhead over the time the other transfers take to complete

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

我将致力于此,但我还没有找到任何关于如何使用 usb4java 完成此操作的好示例。再次感谢您的帮助

关于java - 读取连续传入的数据(usb4java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23493915/

相关文章:

java - Java 应用程序可以在 Android 2.2 设备上使用 USB Host 吗?

c# - 当前连接到 PC 的 USB 设备(友好名称)是什么?

C++ libusb : how to send data to device?

java - 我正在尝试在 GWT 中使用 PieChart。错误 : No source code is available

java - Bean 验证 : How to localize messages programmatically?

android - android_winusb.inf 中的 SingleAdbInterface、CompositeAdbInterface 和 SingleBootLoaderInterface 是什么

c++ - 在 Windows 上,libusb 看不到某些端口

docker --device 使用绝对设备路径,使用符号链接(symbolic link)失败

java - onLocationChange() 未被调用...使用 FuseLocationApi ...检查了所有解决方案并尝试了所有...但仍然没有任何效果

Java:将unix时间(长)舍入到该月的第一天