📄 serial_port_in_win32.txt
字号:
ODDPARITY Odd
StopBits Specifies the number of stop bits to be used. This member can be one of the following values:
Value Meaning
ONESTOPBIT 1 stop bit
ONE5STOPBITS 1.5 stop bits
TWOSTOPBITS 2 stop bits
XonChar Specifies the value of the XON character for both transmission and reception.
XoffChar Specifies the value of the XOFF character for both transmission and reception.
ErrorChar Specifies the value of the character used to replace bytes received with a parity error.
EofChar Specifies the value of the character used to signal the end of data.
EvtChar Specifies the value of the character used to cause the EV_RXFLAG event. This setting does not actually cause anything to happen without the use of EV_RXFLAG in the SetCommMask function and the use of WaitCommEvent.
wReserved1 Reserved; do not use.
Flow Control
Flow control in serial communications provides a mechanism for suspending communications while one of the devices is busy or for some reason cannot do any communication. There are traditionally two types of flow control: hardware and software.
A common problem with serial communications is write operations that actually do not write the data to the device. Often, the problem lies in flow control being used when the program did not specify it. A close examination of the DCB structure reveals that one or more of the following members may be TRUE: fOutxCtsFlow, fOutxDsrFlow, or fOutX. Another mechanism to reveal that flow control is enabled is to call ClearCommError and examine the COMSTAT structure. It will reveal when transmission is suspended because of flow control.
Before discussing the types of flow control, a good understanding of some terms is in order. Serial communications takes place between two devices. Traditionally, there is a PC and a modem or printer. The PC is labeled the Data Terminal Equipment (DTE). The DTE is sometimes called the host. The modem, printer, or other peripheral equipment is identified as the Data Communications Equipment (DCE). The DCE is sometimes referred to as the device.
Hardware flow control
Hardware flow control uses voltage signals on control lines of the serial cable to control whether sending or receiving is enabled. The DTE and the DCE must agree on the types of flow control used for a communications session. Setting the DCB structure to enable flow control just configures the DTE. The DCE also needs configuration to make certain the DTE and DCE use the same type of flow control. There is no mechanism provided by Win32 to set the flow control of the DCE. DIP switches on the device, or commands sent to it typically establish its configuration. The following table describes the control lines, the direction of the flow control, and the line's effect on the DTE and DCE.
Table 3. Hardware Flow-control Lines
Line and Direction Effect on DTE/DCE
CTS
(Clear To Send)
Output flow control DCE sets the line high to indicate that it can receive data. DCE sets the line low to indicate that it cannot receive data.
If the fOutxCtsFlow member of the DCB is TRUE, then the DTE will not send data if this line is low. It will resume sending if the line is high.
If the fOutxCtsFlow member of the DCB is FALSE, then the state of the line does not affect transmission.
DSR
(Data Set Ready)
Output flow control DCE sets the line high to indicate that it can receive data. DCE sets the line low to indicate that it cannot receive data.
If the fOutxDsrFlow member of the DCB is TRUE, then the DTE will not send data if this line is low. It will resume sending if the line is high.
If the fOutxDsrFlow member of the DCB is FALSE, then the state of the line does not affect transmission.
DSR
(Data Set Ready)
Input flow control If the DSR line is low, then data that arrives at the port is ignored. If the DSR line is high, data that arrives at the port is received.
This behavior occurs if the fDsrSensitivity member of the DCB is set to TRUE. If it is FALSE, then the state of the line does not affect reception.
RTS
(Ready To Send)
Input flow control The RTS line is controlled by the DTE.
If the fRtsControl member of the DCB is set to RTS_CONTROL_HANDSHAKE, the following flow control is used: If the input buffer has enough room to receive data (at least half the buffer is empty), the driver sets the RTS line high. If the input buffer has little room for incoming data (less than a quarter of the buffer is empty), the driver sets the RTS line low.
If the fRtsControl member of the DCB is set to RTS_CONTROL_TOGGLE, the driver sets the RTS line high when data is available for sending. The driver sets the line low when no data is available for sending. Windows 95 ignores this value and treats it the same as RTS_CONTROL_ENABLE.
If the fRtsControl member of the DCB is set to RTS_CONTROL_ENABLE or RTS_CONTROL_DISABLE, the application is free to change the state of the line as it needs. Note that in this case, the state of the line does not affect reception.
The DCE will suspend transmission when the line goes low. The DCE will resume transmission when the line goes high.
DTR
(Data Terminal Ready)
Input flow control The DTR line is controlled by the DTE.
If the fDtrControl member of the DCB is set to DTR_CONTROL_HANDSHAKE, the following flow control is used: If the input buffer has enough room to receive data (at least half the buffer is empty), the driver sets the DTR line high. If the input buffer has little room for incoming data (less than a quarter of the buffer is empty), the driver sets the DTR line low.
If the fDtrControl member of the DCB is set to DTR_CONTROL_ENABLE or DTR_CONTROL_DISABLE, the application is free to change the state of the line as it needs. In this case, the state of the line does not affect reception.
The DCE will suspend transmission when the line goes low. The DCE will resume transmission when the line goes high.
The need for flow control is easy to recognize when the CE_RXOVER error occurs. This error indicates an overflow of the receive buffer and data loss. If data arrives at the port faster than it is read, CE_RXOVER can occur. Increasing the input buffer size may cause the error to occur less frequently, but it does not completely solve the problem. Input flow control is necessary to completely alleviate this problem. When the driver detects that the input buffer is nearly full, it will lower the input flow-control lines. This should cause the DCE to stop transmitting, which gives the DTE enough time to read the data from the input buffer. When the input buffer has more room available, the voltage on flow-control lines is set high, and the DCE resumes sending data.
A similar error is CE_OVERRUN. This error occurs when new data arrives before the communications hardware and serial communications driver completely receives old data. This can occur when the transmission speed is too high for the type of communications hardware or CPU. This can also occur when the operating system is not free to service the communications hardware. The only way to alleviate this problem is to apply some combination of decreasing the transmission speed, replacing the communications hardware, and increasing the CPU speed. Sometimes third-party hardware drivers that are not very efficient with CPU resources cause this error. Flow control cannot completely solve the problems that cause the CE_OVERRUN error, although it may help to reduce the frequency of the error.
Software flow control
Software flow control uses data in the communications stream to control the transmission and reception of data. Because software flow control uses two special characters, XOFF and XON, binary transfers cannot use software flow control; the XON or XOFF character may appear in the binary data and would interfere with data transfer. Software flow control befits text-based communications or data being transferred that does not contain the XON and XOFF characters.
In order to enable software flow control, the fOutX and fInX members of the DCB must be set to TRUE. The fOutX member controls output flow control. The fInX member controls input flow control.
One thing to note is that the DCB allows the program to dynamically assign the values the system recognizes as flow-control characters. The XoffChar member of the DCB dictates the XOFF character for both input and output flow control. The XonChar member of the DCB similarly dictates the XON character.
For input flow control, the XoffLim member of the DCB specifies the minimum amount of free space allowed in the input buffer before the XOFF character is sent. If the amount of free space in the input buffer drops below this amount, then the XOFF character is sent. For input flow control, the XonLim member of the DCB specifies the minimum number of bytes allowed in the input buffer before the XON character is sent. If the amount of data in the input buffer drops below this value, then the XON character is sent.
Table 4 lists the behavior of the DTE when using XOFF/XON flow control.
Table 4. Software flow-control behavior
Flow-control character Behavior
XOFF received by DTE DTE transmission is suspended until XON is received. DTE reception continues. The fOutX member of the DCB controls this behavior.
XON received by DTE If DTE transmission is suspended because of a previous XOFF character being received, DTE transmission is resumed. The fOutX member of the DCB controls this behavior.
XOFF sent from DTE XOFF is automatically sent by the DTE when the receive buffer approaches full. The actual limit is dictated by the XoffLim member of the DCB. The fInX member of the DCB controls this behavior. DTE transmission is controlled by the fTXContinueOnXoff member of the DCB as described below.
XON sent from the DTE XON is automatically sent by the DTE when the receive buffer approaches empty. The actual limit is dictated by the XonLim member of the DCB. The fInX member of the DCB controls this behavior.
If software flow control is enabled for input control, then the fTXContinueOnXoff member of the DCB takes effect. The fTXContinueOnXoff member controls whether transmission is suspended after the XOFF character is automatically sent by the system. If fTXContinueOnXoff is TRUE, then transmission continues after the XOFF is sent when the receive buffer is full. If fTXContinueOnXoff is FALSE, then transmission is suspended until the system automatically sends the XON character. DCE devices using software flow control will suspend their sending after the XOFF character is received. Some equipment will resume sending when the XON character is sent by the DTE. On the other hand, some DCE devices will resume sending after any character arrives. The fTXContinueOnXoff member should be set to FALSE when communicating with a DCE device that resumes sending after any character arrives. If the DTE continued transmission after it automatically sent the XOFF, the resumption of transmission would cause the DCE to continue sending, defeating the XOFF.
There is no mechanism available in the Win32 API to cause the DTE to behave the same way as these devices. The DCB structure contains no members for specifying suspended transmission to resume when any character is received. The XON character is the only character that causes transmission to resume.
One other interesting note about software flow control is that reception of XON and XOFF characters causes pending read operations to complete with zero bytes read. The XON and XOFF characters cannot be read by the application, since they are not placed in the input buffer.
A lot of programs on the market, including the Terminal program that comes with Windows, give the user three choices for flow control: Hardware, Software, or None. The Windows operating system itself does not limit an application in this way. The settings of the DCB allow for Software and Hardware flow control simultaneously. In fact, it is possible to separately configure each member of the DCB that affects flow control, which allows for several different flow-control configurations. The limits placed on flow-control choices are there for ease-of-use reasons to reduce confusion for end users. The limits placed on flow-control choices may also be because devices used for communications may not support all types of flow control.
Communications Time-outs
Another major topic affecting the behavior of read and write operations is time-outs. Time-outs affect read and write operations in the following way. If an operation takes longer than the computed time-out period, the operation is completed. There is no error code that is returned by ReadFile, WriteFile, GetOverlappedResult, or WaitForSingleObject. All indicators used to monitor the operation indicate that it completed successfully. The only way to tell that the operation timed out is that the number of bytes actually transferred are fewer than the number of bytes requested. So, if ReadFile returns TRUE, but fewer bytes were read than were requested, the operation timed out. If an overlapped write operation times out, the overlapped event handle is signaled and WaitForSingleObject returns WAIT_OBJECT_O. GetOverlappedResult returns TRUE, but dwBytesTransferred contains the number of bytes that were transferred before the time-out. The following code demonstrates how to handle this in an overlapped write operation:
BOOL WriteABuffer(char * lpBuf, DWORD dwToWrite)
{
OVERLAPPED osWrite = {0};
DWORD dwWritten;
DWORD dwRes;
BOOL fRes;
// Create this write operation's OVERLAPPED structure hEvent.
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL)
// Error creating overlapped event handle.
return FALSE;
// Issue write
if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {
if (GetLastError() != ERROR_IO_PENDING) {
// WriteFile failed, but it isn't delayed. Report error.
fRes = FALSE;
}
else
// Write is pending.
dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(dwRes)
{
// Overlapped event has been signaled.
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))
fRes = FALSE;
else {
if (dwWritten != dwToWrite) {
// The write operation timed out. I now need to
// decide if I want to abort or retry. If I retry,
// I need to send only the bytes that weren't sent.
// If I want to abort, I would just set fRes to
// FALSE and return.
fRes = FALSE;
}
else
// Write operation completed successfully.
fRes = TRUE;
}
break;
default:
// An error has occurred in WaitForSingleObject. This usually
// indicates a problem with the overlapped event handle.
fRes = FALSE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -