串口输入缓冲区的奇怪行为

时间:2012-09-07 08:03:17

标签: c# .net c#-4.0 .net-4.0 serial-port

使用虚拟串口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

获取

1 个答案:

答案 0 :(得分:0)

  

使用虚拟串口w / usbser.sys作为驱动程序

USB仿真器驱动程序通常不会花费太多精力来完美地模拟串行端口。像波特率,奇偶校验和握手这样的东西在USB上没有意义,所以完全被伪造了。这个显然也不会模拟缓冲区大小。

目前尚不清楚为什么要担心它,但这不是问题。您必须始终注意ReadFile()返回的字节数(lpNumberOfBytesRead),它只是偶然等于nNumberOfBytesToRead。所以只需重复调用ReadFile()来填充自己的缓冲区。顺便说一句,使用.NET SerialPort类来避免pinvoke。