0

使用带有 usbser.sys 的虚拟串行端口作为驱动程序;我得到缓冲区的一些奇怪行为。出于性能原因,我使用 Win32 调用(CreateFile、ReadFile 等)而不是 .NET 中的 SerialPort 类。

打开 COM 端口后,我使用 SetupComm(hFile, dwInQueue, dwOutQueue) 将输入缓冲区设置为 32768。我尝试过其他大小,例如。4096、8192等

然后我用 GetCommProperties(hFile, lpCommProp) 读取缓冲区大小并读取 COMMPROP.dwCurrentRxQueue 以检查大小是否已设置。但是无论我尝试设置什么大小,dwCurrentRxQueue 总是返回 16384

为什么?

我有一个 System.Timers.Timer,它每 10 毫秒启动一次并调用 ReadFile(...),然后对字节执行一些操作。当定时器暂停时(例如,通过调用 Thread.Sleep 5 秒),虚拟串行端口的缓冲区逻辑上会填满。睡眠后,我使用 ClearCommError(...) 检查缓冲区中的字节数,读取 COMSTAT 的 cbInqueue。

由于 dwCurrentRxQueue 显然是 16384,因此您希望缓冲区在 5 秒睡眠后被 16K 的数据打包。但是缓冲区永远不会包含超过 ~12K的数据,即使在休眠 10-20-30 秒后也是如此!

为什么?

这是代码的摘录:

_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 回答