使用虚拟串口w / 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,它每隔10ms启动一次并调用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
获取答案 0 :(得分:0)
使用虚拟串口w / usbser.sys作为驱动程序
USB仿真器驱动程序通常不会花费太多精力来完美地模拟串行端口。像波特率,奇偶校验和握手这样的东西在USB上没有意义,所以完全被伪造了。这个显然也不会模拟缓冲区大小。
目前尚不清楚为什么要担心它,但这不是问题。您必须始终注意ReadFile()返回的字节数(lpNumberOfBytesRead),它只是偶然等于nNumberOfBytesToRead。所以只需重复调用ReadFile()来填充自己的缓冲区。顺便说一句,使用.NET SerialPort类来避免pinvoke。