The saga continues...
I'm rapidly coming to the conclusion that my serial device is too pernickety to play nicely with the SerialPort
class provided by System.IO.Ports
.
In order to convincingly pass myself off as the vendor supplied software, I'm attempting to match each aspect of the conversation as recorded by Portmon (logs here) and HHD's Free Serial Monitor开发者_如何学C. Using the managed (.NET) library, I'm unable to replicate the following:
- Special characters. As described in a separate question, SerialPort does not allow the special character set to be changed. It's likely that it's irrelevant, but I'd like to be able to categorically reject it.
Fine-grained timeouts. As described on MSDN, there are 5 timeout settings that dictate the resulting behaviour:
ReadIntervalTimeout
(RI)ReadTotalTimeoutMultiplier
(RM)ReadTotalTimeoutConstant
(RC)WriteTotalTimeoutMultiplier
(WM)WriteTotalTimeoutConstant
(WC).
SerialPort.WriteTimeout(int)
andSerialPort.ReadTimeout(int)
only change the WC and RC settings, which is small problem, but it rather than leaving the others at 0, .NET sets to set RI and RM at -1.Queries during port opening. Between opening the port and setting the baud, both my (.NET) app and the vendor supplied app do a bunch of queries like
IOCTL_SERIAL_GET_LINE_CONTROL
. .NET adds some that the vendor's app doesn't do though, such asIOCTL_SERIAL_GET_MODEMSTATUS
. I'd like to be able to stop this.Superfluous repetition. During port opening a block of commands (setting line control, baud, special characters and handshake, clearing RTS and DTR) are repeated for some reason by .NET. The vendor supplied software jumps straight in after running this block once.
Like I said above, I've no idea whether any of these discrepancies are the cause of my woes, but I'd like to be able to find out. What's more, I think that having greater control over the process will allow me to really hone in on the problem, whatever it turns out to be.
My question then, is how do I hook directly onto the correct API to control the serial port at a nuts-and-bolts level? Any suggestions or guidance appreciated!
It has been a long time since I have done serial stuff, but I remember this guy as a very good resouce - website http://www.lvr.com/serport.htm . Hope that helps.
It appears to have been awhile since this thread was active, but since it has no solution, I figured I'd answer the question for completeness.
Your problem with the re initializing happens because of the default handshake that the SerialPort class uses, I don't know why it does this, but it's really annoying, you can get around this by skipping over the SerialPort properties and delving straight into the DCB struct.
I have made a class in C# full of extension methods for the SerialPort class, take a look at my answer over here on CodeProject
If you do decide to go this route, I'd recommend skipping directly over the SerialPort.Write to SerialPort.BaseStream.Write, they take the same parameters, but I'm pretty sure the SerialPort class does extra unnecessary init stuff there, do the same with SerialPort.Read.
精彩评论