C# で serialport コンポーネントを使用していますが、うまく動作します。しかし問題は、高速 (たとえば 2 Mbps) のデータ転送を処理するために、どうすればより速くできるかということです。
これについて調査したところ、メモリに直接アクセスできることがわかりました(このリンクのようなDMAを使用)。アプリケーションで定義して使用する方法を誰か教えてもらえますか?
C# で serialport コンポーネントを使用していますが、うまく動作します。しかし問題は、高速 (たとえば 2 Mbps) のデータ転送を処理するために、どうすればより速くできるかということです。
これについて調査したところ、メモリに直接アクセスできることがわかりました(このリンクのようなDMAを使用)。アプリケーションで定義して使用する方法を誰か教えてもらえますか?
あなたはそれを完全に間違っていました。
まず第一に、あなたはハードウェア (Windows) に直接アクセスできない環境にいるので、あなたが説明したようなことは、カーネル ドライバーを書かないと基本的に不可能です (そして、あなたはしたくありません、私を信じてください)。
第 2 に、オペレーティング システムとそのドライバーは既に非常に最適化されており、DMA 転送を使用する必要がある場合は既に実行されているはずです。
第 3 に、シリアル コントローラがサポートしていない限り、これらの速度は得られず、通常はサポートされていません。PC の RS232 コントローラは通常、最大 115200 ボーですが、一部のコントローラは最大 1Mb です。
しかし、別のオプションがあります.USBなしでUSBに行きます:D
あなたの質問から、ある種のマイクロコントローラーを PC と接続していて、コントローラー用の USB ドライバーをプログラムしたくない (または USB の機能がない) と思うので、非常に良いオプションはRS-232 - USB ケーブルを使用します。これらは通常、非常に高速な速度をサポートします。私は個人的に FTDI RS-232 3v3 を使用しており、最大 3Mb になります ( http://www.ftdichip.com/Support/Documents/DataSheets/Cables /DS_TTL-232R_CABLES.pdf )。
最後に、通常のシリアル ポート コードをプログラミングしますが、より拡張された USB インターフェイスを使用します (これはもう 1 つの利点です。現在のすべての PC にシリアル ポートが付属しているわけではありません)。
その後、スピードアップの恩恵を受けるには、非常に大きな読み取り/書き込みバッファー (少なくとも 1Mb) をポートに設定し、非ブロックイン受信ルーチンを実行して、大量のデータ (書き込みに収まる必要があります) を送信することを忘れないでください。バッファ)。
デバイスは選択した速度と同じでなければならないことに注意してください。したがって、2 ~ 3Mbps に設定した場合、デバイスはシリアル インターフェイスをまったく同じ速度で実行する必要があります。
以下は、私が説明した受信部分の例です。
SerialPort sp;
Queue<byte[]> buffer = new Queue<byte[]>();
AutoResetEvent dataAvailable = new AutoResetEvent(false);
Thread processThread;
public void Start()
{
//Start the processing thread
processThread = new Thread(ProcessData);
processThread.Start();
//Open the serial port at 3Mbps and with buffers of 3Mb
sp = new SerialPort("COM12", 3145728, Parity.None, 8, StopBits.One);
sp.ReadBufferSize = 1024 * 1024 * 3;
sp.WriteBufferSize = 1024 * 1024 * 3;
sp.DataReceived += sp_DataReceived;
sp.Open();
}
//This thread processes the stored chunks doing the less locking possible
void ProcessData(object state)
{
while (true)
{
dataAvailable.WaitOne();
while (buffer.Count > 0)
{
byte[] chunk;
lock (buffer)
chunk = buffer.Dequeue();
//Process the chunk here as you wish
}
}
}
//The receiving function only stores data in a list of chunks
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (sp.BytesToRead > 0)
{
byte[] chunk = new byte[sp.BytesToRead];
sp.Read(chunk, 0, chunk.Length);
lock (buffer)
buffer.Enqueue(chunk);
dataAvailable.Set();
}
}
シリアル アクセスをこれ以上高速化する必要はないと思います。代わりに、C# アプリケーションを調整して、データ転送を高速化します。選択したプロファイラーを実行し、serialport コンポーネントのメソッドで費やされた時間の割合を測定します。私はそれが非常に低いと予測しています。つまり、シリアルポートを高速化するための努力は無駄に費やされます.