0

ドライバーとして usbser.sys を使用して仮想シリアル ポートを使用します。バッファの奇妙な動作が発生します。パフォーマンス上の理由から、.NET の SerialPort クラスではなく、Win32 呼び出し (CreateFile、ReadFile など) を使用します。

COM ポートを開いた後、SetupComm(hFile, dwInQueue, dwOutQueue) を使用して入力バッファーを 32768 に設定します。4096、8192など

次に、GetCommProperties(hFile, lpCommProp) を使用してバッファー サイズを読み取り、COMMPROP.dwCurrentRxQueue を読み取って、サイズが設定されているかどうかを確認します。しかし、どのようなサイズを設定しようとしても、dwCurrentRxQueue は常に 16384 を返します

なんで?

10ms ごとに起動して ReadFile(...) を呼び出し、バイトで何かを行う System.Timers.Timer があります。タイマーが中断されると (たとえば、Thread.Sleep を 5 秒間呼び出して)、仮想シリアル ポートのバッファが論理的にいっぱいになります。スリープ後、ClearCommError(...) を使用してバッファ内のバイト数を確認し、COMSTAT の cbInqueue を読み取ります。

dwCurrentRxQueue は明らかに 16384 であるため、5 秒間スリープした後、バッファには 16K のデータが詰め込まれていると予想されます。ただし、 10 ~ 20 ~ 30 秒間スリープした後でも、バッファーに最大 12K を超えるデータが含まれることはありません。

なんで?

コードの抜粋を次に示します。

_handle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

SetupComm(_handle, 32768, 32768)

// ... other calls (SetCommState, SetCommConfig, SetCommTimeouts)

var commprop = new COMMPROP();

GetCommProperties(_handle, ref commprop)

// commprop.dwCurrentRxQueue always returns 16384

System.Threading.Thread.Sleep(5000);

COMSTAT comstat;
uint    errors;

ClearCommError(_handle, out errors, out comstat);

// comstat.cbInQueue never contains more than ~12 KBytes :s

メソッドと構造体のシグネチャは pinvoke.net から取得されました

4

1 に答える 1

0

ドライバーとして usbser.sys を使用した仮想シリアル ポートの使用

通常、USB エミュレーター ドライバーは、シリアル ポートを完全にシミュレートするために多大な労力を費やしません。ボーレート、パリティ、ハンドシェークなどは USB では意味を成さないため、完全に偽装されています。これも明らかにバッファサイズをエミュレートしていません。

なぜあなたがそれについて心配しているのかは明らかではありませんが、それは問題ではありません. ReadFile() が返すバイト数 (lpNumberOfBytesRead) に常に注意を払う必要があります。たまたま nNumberOfBytesToRead と等しいだけです。したがって、 ReadFile() を繰り返し呼び出して、独自のバッファーを埋めるだけです。ところで、.NET SerialPort クラスを使用して pinvoke を回避します。

于 2012-09-07T10:23:01.917 に答える