|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
.Net 2 SerialPort Class QuestionsI am working to port an existing application from .net 1.1 to 2.0 and we hope to employ the new SerialPort class. In our application, the SerialPort class instance is "wired" to a virtual serial port that is Win32-based. So when changes take place to the virtual port, we need to migrate those changes to the serial port and vis-a-vis. The previous version of our code was using a serial port class based on the Win32 API (derived from the one found at <http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/default.aspx>). In porting to the .net 2 SerialPort, I have a few issues: I am having some confusion about how to map the Win32 notion of serial port timeouts to that in the .Net 2 SerialPort class. The new class offers a single property each for ReadTimeout and WriteTimeout. These are documented as: "Gets or sets the number of milliseconds before a time-out occurs when a read (or write) operation does not finish." In the Win32 API, timeouts do not seem this simple and they do not seem to map easily as their values are based since the last byte was received or sent and their are multipliers and constants. Has anyone out there managed to make any sense of how to map the Win32 API sense of timeouts to that in the new .Net class? Also, the same thing seems an issue with the idea of Hanshaking? Any suggestions here? Thanks, David Hi David,
Why do Timouts concern you? The default should be fine. A send timeout will only occur when hardware or software flowcontrol has inhibited the transmission of data. The default, I think, is 5000 mS, so as long as the device (or software, in this case) has not signalled that the ..NET application stop sending, then a timeout won't happen. A receive timeout will happen if your app requests data from the port, but there is no data to receive (within the timeout period). There is no obvious reason for this to happen at all. However, the timeouts specified in the SerialPort class do map EXACTLY to those in the Device Control Block of the SetCommState API. So, it isn't clear to me what's up. Also, I don't understand the question about Handshaking. These settings also map directly. You either have no handshaking (flowcontrol), you have CTS/RTS (hardware), you have Xon/Xoff (software), or in some oddball setups you might have both CTS/RTS and Xon/Xoff (both hardware and software flow control). Again, since you are using a virtual serial port, it isn't obvious to me how flowcontrol applies. I suspect that I haven't answered your questions, because I don't have a grip on them. Dick -- Richard Grier, MVP Hard & Software Author of Visual Basic Programmer's Guide to Serial Communications, Fourth Edition, ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March 2006. See www.hardandsoftware.net for details and contact information. Thanks for the response Dick. You may be correct that my questions were not
very clear. It is, I am sure, because I am such a newbie at all this serial comm stuff. I agree that send timeouts should be unimportant. But applications talking to my virtual port do seem to be setting them and I feel that I need to propogate those settings to my SerialPort instance so that the SerialPort mirrors the virtual port to the fullest extent possible. I feel I need to do this because I really do not wish to interfere with what the application is trying to do (any more than I am in general by inserting a virtual to physical layer). So that raises all these issues. I am not sure why you say "the timeouts specified in the SerialPort class do map EXACTLY to those in the Device Control Block of the SetCommState API". That function takes a DCB and I see nothing about timeouts in that structure's definition. Perhaps you mean SetCommTimeouts? This is where I was coming from. But when I read the docs for the members of the COMMTIMEOUTS structure I see: (a) ReadIntervalTimeout (b) ReadTotalTimeoutConstant (c) ReadTotalTimeoutMultiplier The docs for this structure all talk about how the values are combined to yield the "total timeout period for read operations". And the total seems to be a function of the number of bytes to be read. From the SerialPort class docs, I get the feeling (although there is still room for doubt) that the ReadTimeout property is a "total timeout period". But I am not sure about this or about how the number of bytes to be read figure into the equation. I cannot see how the number of bytes to be read can be used by the SerialPort class in calls to ReadLine where the number of bytes ultimately to be read is unknown at the time the read begins. So I guess the question really should have been: How should I combine the values I get when SetCommTimeouts is called to compute the requested value to passed to the single, ReadTimeout property of the SerialPort class? I guess the same would apply to the write timeout but maybe I get away with always using infinite on that. Does this help focus my question any? I hope so. Regards handshaking: again, I am trying to propogate settings made by an application to the virtual port onto the SerialPort instance. Handshake seems the domain of the DCB and SetCommState. In the DCB, I see two members which seem to relate to the details of CTS/RTS hardware handshaking: (a) OutxCtsFlow (b) RtsControl Also, can't DSR/DTR be used in hardware handshaking? I am not sure if DSR/DTR is simply not used any more (and can be ignored). Can DSR/DTR be specified in conjunction with RTS/CTS in the DCB? If so, are these included when Hardware handshaking is specified for the SerialPort class (or is it, as you imply, only CTS/RTS)? If the application requests DSR/DTR via the following: (c) OutxDsrFlow (d) DtrControl What is the proper course with the SerialPort class? I suppose that what I am looking for is something like a big truth table which shows how various combinations of DCB handshake settings should be mapped into the set of values that can be specified on the SerialPort class. Similarly I wonder about the interpretation of the OutX and OutIn flags plus the XContinueOnXoff flag. Again, my confusion is likely due to my high level of ignorance in serial port matters. I just generally feel that I should be trying tp propogate the settings requested on the virtual port into the SerialPort instance. Your help is greatly appreciated. Thanks. Dick Grier wrote: Show quote > Hi David, > > Why do Timouts concern you? The default should be fine. > > A send timeout will only occur when hardware or software flowcontrol has > inhibited the transmission of data. The default, I think, is 5000 mS, so as > long as the device (or software, in this case) has not signalled that the > .NET application stop sending, then a timeout won't happen. > > A receive timeout will happen if your app requests data from the port, but > there is no data to receive (within the timeout period). There is no > obvious reason for this to happen at all. > > However, the timeouts specified in the SerialPort class do map EXACTLY to > those in the Device Control Block of the SetCommState API. So, it isn't > clear to me what's up. > > Also, I don't understand the question about Handshaking. These settings > also map directly. You either have no handshaking (flowcontrol), you have > CTS/RTS (hardware), you have Xon/Xoff (software), or in some oddball setups > you might have both CTS/RTS and Xon/Xoff (both hardware and software flow > control). Again, since you are using a virtual serial port, it isn't > obvious to me how flowcontrol applies. > > I suspect that I haven't answered your questions, because I don't have a > grip on them. > > Dick Hi,
I doubt seriously that the timeouts will be an issue. These apply in only the most obscure situations (and even then, on the TransmitTimeout -- for very slow data transfer). Here is the way that I show them in the classes that I have written: Private Structure COMMTIMEOUTS Public ReadIntervalTimeout As Int32 ' Specifies the maximum acceptable time, in milliseconds, to elapse between the arrival of two characters on the communication line. Public ReadTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in milliseconds, used to calculate the total time-out period for read operations. Public ReadTotalTimeoutConstant As Int32 ' Specifies the constant, in milliseconds, used to calculate the total time-out period for read operations. Public WriteTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in milliseconds, used to calculate the total time-out period for write operations. Public WriteTotalTimeoutConstant As Int32 ' Specifies the constant, in milliseconds, used to calculate the total time-out period for write operations. End Structure The actual timeout in either situatio (ReadTimeout or WriteTimeout) is the xTotalTimeoutConstant multiplied by the xTotalTimeMultiplier. The result is in mS. Dick -- Richard Grier, MVP Hard & Software Author of Visual Basic Programmer's Guide to Serial Communications, Fourth Edition, ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March 2006. See www.hardandsoftware.net for details and contact information. Thanks Dick. I will follow your lead. After all, you wrote the book!
Any comment/suggestion on how to properly decode handshake info from a DCB into the SerialPort class? Cheers, David Dick Grier wrote: Show quote > Hi, > > I doubt seriously that the timeouts will be an issue. These apply in only > the most obscure situations (and even then, on the TransmitTimeout -- for > very slow data transfer). > > Here is the way that I show them in the classes that I have written: > > Private Structure COMMTIMEOUTS > > Public ReadIntervalTimeout As Int32 ' Specifies the maximum acceptable time, > in milliseconds, to elapse between the arrival of two characters on the > communication line. > > Public ReadTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in > milliseconds, used to calculate the total time-out period for read > operations. > > Public ReadTotalTimeoutConstant As Int32 ' Specifies the constant, in > milliseconds, used to calculate the total time-out period for read > operations. > > Public WriteTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in > milliseconds, used to calculate the total time-out period for write > operations. > > Public WriteTotalTimeoutConstant As Int32 ' Specifies the constant, in > milliseconds, used to calculate the total time-out period for write > operations. > > End Structure > > The actual timeout in either situatio (ReadTimeout or WriteTimeout) is the > xTotalTimeoutConstant multiplied by the xTotalTimeMultiplier. The result is > in mS. > > Dick Hi,
I go into this in a little more detail in my book (and, it is somewhat tricky). Here is the routine that I use for flowcontrol (this is controlled by bit-mapped values in the DCB, as isthe Parity setting): Private Sub SetBits(ByRef DCB As DCB) With DCB If m_Parity = 0 Then ..Bits = .Bits And (FPARITY Xor &HFFFF) Else ..Bits = .Bits Or FPARITY End If If m_EnableHardwareFlowcontrol = False Then ..Bits = .Bits And (FOUTXCTSFLOW Xor &HFFFF) ..Bits = .Bits And (FRTSCONTROL Xor &HFFFF) Else ..Bits = .Bits Or FOUTXCTSFLOW ..Bits = .Bits Or FRTSCONTROL End If If m_EnableSoftwareFlowcontrol = False Then ..Bits = .Bits And (FOUTX Xor &HFFFF) ..Bits = .Bits And (FINX Xor &HFFFF) Else ..Bits = .Bits Or FOUTX ..Bits = .Bits Or FINX End If End With End Sub The contants you see are described in the DCB documentation. Dick -- Richard Grier, MVP Hard & Software Author of Visual Basic Programmer's Guide to Serial Communications, Fourth Edition, ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March 2006. See www.hardandsoftware.net for details and contact information. |
|||||||||||||||||||||||