我們有一個帶有一些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);
}
我想一個簡單的測試將是權力的範圍,評論寫作文件,並給它一個測試! – Tim 2010-07-27 15:39:51
@Tim,這是答案。最重要的限制是「線程安全」要求。您將創建一個在兩個線程之間共享的互斥鎖,在隊列被寫入/讀取時鎖定。這裏的技巧是在文件寫入線程中,您應該鎖定,將大塊數據複製到本地緩衝區,然後解鎖。不要再鎖定任何時間,否則你的兩個線程在一個線程上沒有優勢。 – 2010-07-27 15:41:36
其實我使用NO mutx - 使用的方式太多了。我使用一個Spinlock(新的.NET 4.0),因爲我的代碼除了從隊列中取出或放入其他東西外);最重要的是,如果你在每個項目上創建新的緩衝區(就像我一樣),你真的只會鎖定在插入/檢索...沒有複製操作。 – TomTom 2010-07-27 15:43:21