0
votes

Using a virtual serial port w/usbser.sys as driver; I get some strange behavior of the buffers. I use Win32 calls (CreateFile, ReadFile, etc) rather than the SerialPort class in .NET for performance reasons.

After opening the COM port, I use SetupComm(hFile, dwInQueue, dwOutQueue) to set the input buffer to 32768. I've tried with other sizes, eg. 4096, 8192, etc.

Then I read the buffer size back with GetCommProperties(hFile, lpCommProp) and read the COMMPROP.dwCurrentRxQueue to check if the size has been set. But whatever size I try to set, the dwCurrentRxQueue always returns 16384!

Why?

I've got a System.Timers.Timer that kicks in every 10ms and calls ReadFile(...) and then does something with the bytes. When the timer is suspended (eg. by calling Thread.Sleep for 5 secs) the buffer of the virtual serial port logically fills up. After sleeping, I check the number of bytes in the buffer using ClearCommError(...), reading cbInqueue of COMSTAT.

Since the dwCurrentRxQueue apparently is 16384, you'd expect the buffer to be packed with 16K of data after a 5 sec sleep. But the buffer never contains more than ~12K of data, even after sleeping for 10-20-30 secs!

Why?

Here's an excerpt of the code:

_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

Method and structure signatures have been fetched from pinvoke.net

1

1 Answers

0
votes

Using a virtual serial port w/usbser.sys as driver

USB emulator drivers generally don't make much effort to simulate a serial port perfectly. Things like baudrate, parity and handshaking just don't make sense on USB so are completely faked out. This one clearly doesn't emulate a buffer size either.

It isn't clear why you worry about it but it is a non-issue. You must always pay attention to the number of bytes (lpNumberOfBytesRead) that ReadFile() returns, it is only ever equal to nNumberOfBytesToRead by accident. So just call ReadFile() repeatedly to fill your own buffer. Btw, use the .NET SerialPort class to avoid the pinvoke.