2010-07-27 61 views
6

我們有一個帶有一些FPGA和一個FTDI USB控制器的硬件系統。硬件通過USB將數據以大約5MB/s的速度傳輸到PC,軟件的任務是保持同步,檢查CRC並將數據寫入文件。修正流式傳輸USB數據中的間隙

FTDI芯片有一個'繁忙'的引腳,它在等待個人電腦開展業務時處於高位。 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); 
    } 

回答

4

提示:不要寫入文件....隊列。

現代計算機有多個處理器。如果你想盡可能快地使用某些東西,可以使用多個處理器。

  • 有線程處理USB數據,檢查校驗和等。它將結果排隊(僅)到線程安全隊列。
  • 另一個線程從隊列中讀取數據並將其寫入一個可能被緩衝的文件。

成品;)

100ms的是大量的時間體面操作。我已經使用C#成功管理了每秒250,000個IO數據包(財務數據),而且沒有出汗。

基本上,確保你的IO線程只做,並使用你的內部存儲器作爲緩衝區。特別是在一端處理硬件時,執行該操作的線程應該只能執行該操作,如果需要,可能會以高優先級運行。

+1

我想一個簡單的測試將是權力的範圍,評論寫作文件,並給它一個測試! – Tim 2010-07-27 15:39:51

+0

@Tim,這是答案。最重要的限制是「線程安全」要求。您將創建一個在兩個線程之間共享的互斥鎖,在隊列被寫入/讀取時鎖定。這裏的技巧是在文件寫入線程中,您應該鎖定,將大塊數據複製到本地緩衝區,然後解鎖。不要再鎖定任何時間,否則你的兩個線程在一個線程上沒有優勢。 – 2010-07-27 15:41:36

+1

其實我使用NO mutx - 使用的方式太多了。我使用一個Spinlock(新的.NET 4.0),因爲我的代碼除了從隊列中取出或放入其他東西外);最重要的是,如果你在每個項目上創建新的緩衝區(就像我一樣),你真的只會鎖定在插入/檢索...沒有複製操作。 – TomTom 2010-07-27 15:43:21

0

那麼你的接收代碼是什麼樣的?你有一個高優先級的線程,只負責捕獲數據並以非阻塞的方式將它傳遞到另一個線程?您是否以更高的優先級運行流程?

您是否設計了其餘代碼以避免更昂貴的第二代垃圾回收?你有多大的緩衝區,他們在大對象堆?你有效地重用它們嗎?

+0

我正在使用FTDI庫中的'received data'事件。它調用我的函數並將它傳遞給byte []。它通常總是4k ...我會用一些代碼更新這個問題... – Tim 2010-07-27 15:47:52

2

爲了在USB上的Windows上獲得良好的讀取吞吐量,您通常需要有多個排隊到USB設備堆棧上的異步讀取(或讀取非常大的數據,這通常不太方便)。我不太確定FTDI驅動程序/庫在內部在這方面做了什麼。

傳統上,我已經編寫了一系列帶有OVERLAPPED結構和緩衝區數組的機制,並在它們空閒時立即將它們鏟入ReadFile中。大約在5-6年前,我在USB2上做了40 MB/s的讀取,所以現代PC肯定能夠應付。

您(或您的驅動程序/庫)不會進入「開始讀取,完成讀取,處理數據,開始另一個讀取」循環,這是非常重要的,因爲您會發現總線閒置着大量的時間。 USB分析儀會告訴你這是否發生。

我同意其他人,你應該下車線程的是讀儘快發生的一切 - 不要阻擋FTDI事件處理程序,任何比在需要把緩衝到另一個隊列更長。

我會預先分配一個循環隊列的緩衝區,挑選下一個空閒的隊列並將接收到的數據放入其中,然後儘快完成事件處理。

所有校驗和與其伴隨的內存分配,垃圾收集等級連接都可以在PC的緩衝區時間/空間的潛在數百MB的緩衝區中完成。目前,您可能正在有效地詢問您的FPGA /硬件緩衝區,以適應您花費大量時間完成各種繁重PC工作的時間。

雖然我很樂觀 - 如果你真的可以在硬件上緩衝100ms的數據,你應該能夠可靠地工作。我希望我可以說服我的所有客戶允許這麼多...

+0

我們已經得到了大約10ms的緩衝區:-) – Tim 2010-07-27 16:53:29

+0

我仍然認爲你可能會應付10ms,只要你不需要不必要地拖延閱讀器。你在英國的哪個地方? – 2010-07-27 19:34:23