Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修复流式USB数据中的漏洞_C#_.net_Usb - Fatal编程技术网

C# 修复流式USB数据中的漏洞

C# 修复流式USB数据中的漏洞,c#,.net,usb,C#,.net,Usb,我们有一个带有FPGA和FTDI USB控制器的硬件系统。硬件通过USB以大约5MB/s的速度大容量传输数据到PC,软件的任务是保持同步、检查CRC并将数据写入文件 FTDI芯片有一个“忙”引脚,在等待PC完成其业务时,该引脚会变高。FTDI和其他硬件上的缓冲量有限 繁忙线路持续时间超过硬件缓冲区的时间(50-100ms),因此我们正在丢失数据。为了避免我们不得不重新设计硬件,我被要求“修复”这个问题 我认为我的代码足够快,因为我们已经让它运行到15MB/s,所以在某些地方留下了IO瓶颈。我们是

我们有一个带有FPGA和FTDI USB控制器的硬件系统。硬件通过USB以大约5MB/s的速度大容量传输数据到PC,软件的任务是保持同步、检查CRC并将数据写入文件

FTDI芯片有一个“忙”引脚,在等待PC完成其业务时,该引脚会变高。FTDI和其他硬件上的缓冲量有限

繁忙线路持续时间超过硬件缓冲区的时间(50-100ms),因此我们正在丢失数据。为了避免我们不得不重新设计硬件,我被要求“修复”这个问题

我认为我的代码足够快,因为我们已经让它运行到15MB/s,所以在某些地方留下了IO瓶颈。我们是不是对PC/OS的期望太高了

这是我的数据输入点。有时我们会丢失一个位或字节。如果校验和不计算,我会一直移动直到它计算。字节[]数据几乎总是4k

    void ftdi_OnData(byte[] data)
    {
        List<byte> buffer = new List<byte>(data.Length);
        int index = 0;

        while ((index + rawFile.Header.PacketLength + 1) < data.Length)
        {
            if (CheckSum.CRC16(data, index, rawFile.Header.PacketLength + 2)) // <- packet length + 2 for 16bit checksum
            {
                buffer.AddRange(data.SubArray<byte>(index, rawFile.Header.PacketLength));                 
                index += rawFile.Header.PacketLength + 2; // <- skip the two checksums, we dont want to save them...
            }
            else
            {
                index++; // shift through
            }
        }

        rawFile.AddData(buffer.ToArray(), 0, buffer.Count);
    }
void ftdi_OnData(字节[]数据)
{
列表缓冲区=新列表(data.Length);
int指数=0;
而((index+rawFile.Header.PacketLength+1)if(CheckSum.CRC16(数据、索引、rawFile.Header.PacketLength+2))//提示:不要写入文件…队列

现代计算机有多个处理器。如果你想让某些东西尽可能快,就使用多个处理器

  • 让线程处理USB数据、检查校验和等。它(仅)将结果排队到线程安全队列
  • 另一个线程从队列中读取数据并将其写入一个文件(可能已缓冲)
完成;)

100毫秒对于良好的操作来说是一段很长的时间。我使用C#毫不费力地成功管理了每秒约25万个IO数据包(金融数据)


基本上,确保IO线程只执行此操作,并将内部内存用作缓冲区。特别是在处理一端的硬件时,执行此操作的线程应该只执行此操作,如果需要以高优先级运行的话。

那么接收代码是什么样子的呢?是否有一个以高优先级运行的线程专门负责capt对数据进行加密并以非阻塞方式将其在内存中传递给另一个线程?是否以提升的优先级运行进程本身


您是否设计了其他代码以避免更昂贵的第二代垃圾收集?您的缓冲区有多大,它们在大型对象堆上吗?您是否有效地重用它们?

要在Windows on USB上获得良好的读取吞吐量,您通常需要进行多个异步读取(或者非常大的读取,这通常不太方便)排队到USB设备堆栈上。我不太确定FTDI驱动程序/库在这方面的内部功能

传统上,我用一组重叠结构和一组缓冲区编写机制,并在空闲时将它们放入ReadFile。大约5-6年前,我在USB2上进行了40+MB/s的读取,所以现代PC肯定能够应付

非常重要的是,您(或您的驱动程序/库)不要进入“开始读取、完成读取、处理数据、开始另一次读取”循环,因为您会发现总线在很大一段时间内处于空闲状态。USB分析仪会向您显示是否发生了这种情况

我同意其他人的观点,即您应该尽快脱离正在进行读取的线程—不要阻塞FTDI事件处理程序的时间超过将缓冲区放入另一个队列所需的时间

我会预先分配一个缓冲区的循环队列,选择下一个空闲队列并将接收到的数据扔进其中,然后尽快完成事件处理

所有的校验和连接及其伴随的内存分配、垃圾收集等,都可以在PC上潜在的100MB缓冲时间/空间的另一端完成。目前,您可能会有效地要求您的FPGA/硬件缓冲区容纳您完成各种繁重PC工作所需的时间可以迟些做


不过我很乐观——如果你真的能在硬件上缓冲100ms的数据,你应该能够可靠地工作。我希望我能说服我所有的客户允许这么多…

我想一个简单的测试就是给示波器通电,注释写入文件并进行测试!@Tim,这是答案。最重要的条件是它是“线程安全的”要求。您将创建一个互斥锁,该互斥锁在两个线程之间共享,并在队列写入/读取时锁定。这里的诀窍是,在文件写入线程中,您应该锁定,将一块数据复制到本地缓冲区,然后解锁。不要锁定超过必须锁定的时间,否则您的两个线程将没有优势事实上,我使用NO mutx的时间太长了。我使用了一个自旋锁(在.net 4.0中是新的),因为如果你在每个项目上创建新的缓冲区(就像我一样),我的代码只会从队列中取出一些东西或把它放在上面;)你真的只锁定插入/检索…没有拷贝操作。感谢Spinlock的提示,我必须在3.5的时候检查它。我主要是C++程序,所以我天生就喜欢固定大小的缓冲区,因为复制/解除分配和伴随堆碎片在一个NO中更为合适,因此会导致额外的复制成本。n-垃圾收集系统。我在一次高速数据aq后用完了堆。之前,由于堆碎片,我已经运行了几天。使用垃圾收集器,不断分配新缓冲区并避免复制可能更有效。我正在使用FTDI库中的“received data”事件。它调用我的函数并传递字节[].通常都是4k…我会用一些代码更新这个问题…我们有大约10毫秒的缓冲区:-)我仍然认为你可能会应付10毫秒,只要你不