Flow control (= handshaking = pacing) is to prevent too fast of a flow of bytes from overrunning a terminal, computer, modem or other device. Overrunning is when a device can't process what it is receiving quickly enough and thus loses bytes and/or makes other serious errors. What flow control does is to halt the flow of bytes until the terminal (for example) is ready for some more bytes. Flow control sends its signal to halt the flow in a direction opposite to the flow of bytes it wants to stop. Flow control must both be set at the terminal and at the computer.
There are 2 types of flow control: hardware and software (Xon/Xoff or DC1/DC3). Hardware flow control uses dedicated signal wires such as RTS/CTS or DTR while software flow control signals by sending DC1 or DC3 control bytes in the normal data wires. For hardware flow control, the cable must be correctly wired.
The flow of data bytes in the cable between 2 serial ports is bi-directional so there are 2 different flows (and wires) to consider:
You might ask: "Why not send at a speed slow enough so that the device will not be overrun and then flow control is not needed?" This is possible but it's usually significantly slower than sending faster and using flow control. One reason for this is that one can't just set the serial port baud rate at any desired speed such as 14,500, since only a discrete number of choices are available. The best choice is to select a rate that is a little higher than the device can keep up with but then use flow control to make things work right.
If one decides to not use flow control, then the speed must be set low enough to cope with the worst case situation. For a terminal, this is when one sends escape sequences to it to do complex tasks that take more time than normal. In the case of a modem (with data compression but no flow control) the speed from the computer to the modem must be slow enough so that this same speed is usable on the phone line, since in the worst case the data is random and can't be compressed. If one failed to use flow control, the speed (with data compression turned on) would be no faster than without using any compression at all.
Buffers are of some help in handling worst case situations of short duration. The buffer stores bytes that come in too fast to be processed at once, and saves them for processing later.
Another way to handle a "worst case" situation (without using flow control or buffers) is to add a bunch of nulls (bytes of value zero) to escape sequences. Sometimes DEL's are used instead provided they have no other function. See Recognize Del.
The escape sequence starts the terminal doing something, and while the
terminal is busy doing it, it receives a bunch of nulls which it
ignores. When it gets the last null, it has completed its task and is
ready for the next command. This is called null padding. These nulls
formerly were called "fill characters". These nulls are added just to
"waste" time, but it's not all wasted since the terminal is usually
kept busy doing something else while the nulls are being received. It
was much used in the past before flow control became popular. To be
efficient, just the right amount of nulls should be added and figuring
out this is tedious. It was often done by trial and error since
terminal manuals are of little or no help. If flow control doesn't
work right or is not implemented, padding is one solution. Some of
the options to the stty
command involve padding.
One might wonder how overrunning is possible at a serial port since both the sending and receiving serial ports involved in a transmission of data bytes are set for the same speed (in bits/sec) such as 19,200. The reason is that although the receiving serial port electronics can handle the incoming flow rate, the hardware/software that fetches and processes the bytes from the serial port sometimes can't cope with the high flow rate.
One cause of this is that the serial port's hardware buffer is quite small. Older serial ports had a hardware buffer size of only one byte (inside the UART chip). If that one received byte of data in the buffer is not removed (fetched) by CPU instructions before the next byte arrives, that byte is lost (the buffer is overrun). Newer UART's, namely most 16550's, have 16-byte buffers (but may be set to emulate a one-byte buffer) and are less likely to overrun. It may be set to issue an interrupt when the number of bytes in its buffer reaches 1, 4, 8, or 14 bytes. It's the job of another computer chip (usually the main CPU chip for a computer) to take these incoming bytes out of this small hardware buffer and process them (as well as perform other tasks).
When contents of this small hardware receive buffer reaches the specified limit (one byte for old UART'S) an interrupt is issued. Then the computer interrupts what it was doing and software checks to find out what happened. It finally determines that it needs to fetch a byte (or more) from the serial port's buffer. It takes these byte(s) and puts them into a larger buffer (also a serial port buffer) that the kernel maintains in main memory. For the transmit buffer, the serial hardware issues an interrupt when the buffer is empty (or nearly so) to tell the CPU to put some more bytes into it to send out.
Terminals also have serial ports and buffers similar to the computer. Since the flow rate of bytes to the terminal is usually much greater than the flow in the reverse direction from the keyboard to the host computer, it's the terminal that is most likely to suffer overrunning. Of course, if you're using a computer as a terminal (by emulation), then it is likewise subject to overrunning.
Risky situations where overrunning is more likely are: 1. When another process has disabled interrupts (for a computer). 2. When the serial port buffer in main (or terminal) memory is about to overflow.
When its appears that the receiver is about to be overwhelmed by incoming bytes, it sends a signal to the sender to stop sending. That is flow control and the flow control signals are always sent in a direction opposite to the flow of data which they control (although not in the same channel or wire). This signal may either be a control character (^S = DC3 = Xoff) sent as an ordinary data byte on the data wire (in-band signalling), or a voltage transition from positive to negative in the dtr-to-cts (or other) signal wire (out-of-band signalling). Using Xoff is called "software flow control" and using the voltage transition in a dedicated signal wire (inside the cable) is called hardware flow control.
When a terminal is told to stop sending, the terminal "locks" its keyboard. This seldom happens but when it does, a message or light should inform you that the keyboard is locked. Anything you type at a locked keyboard is ignored. The term "locked" is also used when the computer is told to stop sending to a terminal. The keyboard is not locked so that whatever you type goes to the computer. Since the computer can't send anything back to you, characters you type don't display on the screen and it may seem like the keyboard is locked but it's not.
When the receiver has caught up with its processing and is ready to receive more data bytes it signals the sender. For software flow control this signal is the control character ^Q = DC1 = Xon which is sent on the regular data line. For hardware flow control the voltage in a signal line goes from negative (negated) to positive (asserted). If a terminal is told to resume sending the keyboard is then unlocked and ready to use.
Some older terminals have no hardware flow control while others used a wide assortment of different pins on the serial port for this. The most popular today seems to be the DTR pin.
Linux PC's use RTS/CTS, but DTR flow control (used by many terminals) behaves similarly (except it is usually only in one direction). RTS/CTS uses the pins RTS and CTS on the serial (EIA-232) connector. RTS means "Request To Send". When this pin stays asserted (positive voltage) at the receiver it means: keep sending data to me. If RTS is negated (voltage goes negative) it negates "Request To Send" which means: request not to send to me (stop sending). When the receiver is ready for more input, it asserts RTS requesting the other side to resume sending. For computers and terminals (both DTE type equipment) the RTS pin sends the flow control signal to the CTS pin (Clear To Send) on the other end of the cable. That is, the RTS pin on one end of the cable is connected to the CTS pin at the other end.
For a modem (DCE equipment) it's a different scheme since the modem's RTS pin receives the signal and its CTS pin sends. While this may seem confusing, there are valid historical reasons for this which are too involved to discuss here.
For DTR flow control at a terminal, the DTR signal is like the signal sent from the RTS pin. This DTR pin should connects to the host's CTS pin.
Many terminals use DTR flow control. This is only one-way flow control to keep the terminal from being overrun. It doesn't protect the computer from someone typing too fast for the computer to handle it. In a standard null modem cable the DTR pin at the terminal is connected to the DSR pin at the computer. But Linux doesn't support DTR/DSR flow control (although drivers for some multiport boards may support DTR/DSR flow control.) A way around this problem is to simply wire the DTR pin at the computer to connect to the CTS pin at the computer and set RTS/CTS flow control (stty crtscts). The fact that it's only one way will not affect anything so long as the host doesn't get overwhelmed by your typing speed and drop RTS in a vain attempt to lock your keyboard. See Keyboard Lock.
What is confusing is that there is the original use of RTS where it means about the opposite of the previous explanation above. This original meaning is: I Request To Send to you. This request was intended to be sent from a terminal (or computer) to a modem which, if it decided to grant the request, would send back an asserted CTS from its CTS pin to the CTS pin of the computer: You are Cleared To Send to me. Note that in contrast to the modern RTS/CTS bi-directional flow control, this only protects the flow in one direction: from the computer (or terminal) to the modem.
For older terminals, RTS may have this meaning and goes high when the terminal has data to send out. The above use is a form of flow control since if the modem wants the computer to stop sending it drops CTS (connected to CTS at the computer) and the computer stops sending.
Old hard-copy terminals may have a reverse channel pin (such as pin 19) which behaves like the RTS pin in RTS/CTS flow control. This pin but will also be negated if paper or ribbon runs out. It's often feasible to connect this pin to the CTS pin of the host computer. There may be a dip switch to set the polarity of this signal.
Some think that hardware flow control is done by hardware but (unless you are using an intelligent serial card with several serial ports) it's actually done by your operating system software. UART chips and associated hardware usually know nothing at all about hardware flow control. When a hardware flow control signal is received, the signal wire flips polarity and the hardware gives an electrical interrupt signal to the CPU. However, the hardware has no idea what this interrupt means. The CPU stops what it was doing and jumps to a table in main memory that tells the CPU where to go to find a program which will find out what happened and what to do about it.
It's this program (part of the serial device driver) that stops (or resumes) the sending. This program checks the contents of registers in the UART chip to find out that a certain wire has changed polarity. Then the software realizes that a flow control signal has been received and goes about stopping (or starting) the flow. However, if it's a stop signal that has been received, the flow stops almost instantly when the signal arrives because the interrupt has stopped whatever the CPU was doing (including the program that was sending the data and putting it in the serial ports hardware buffers for transmission). However any bytes (up to 16) which were already in the serial port's hardware transmit buffer will still get transmitted ?? Thus the hardware almost instantly stops the flow only because it's reaction to a hardware signal is to interrupt and stop everything the CPU was doing.
This is also software flow control and requires a device driver that knows about it. Bytes are sent in packets (via the async serial port) with each packet terminated by an ETX (End of Text) control character. When the terminal gets an ETX it waits till it is ready to receive the next packet and then returns an ACK (Acknowledge). When the computer gets the ACK, it then send the next packet. And so on. This is not supported by Linux ?? Some HP terminals use the same scheme but use ENQ instead of ETX.