Assume your modem is on COM2:. Its minor number will be 65, and its major number will be 4 for normal use. There should be a device called ttyS1 that has these numbers. List the serial ttys in the /dev/ directory. The fifth and sixth columns show the major and minor numbers, respectively:
$ ls -l /dev/ttyS*
0 crw-rw-- 1 uucp dialout 4, 64 Oct 13 1997 /dev/ttyS0
0 crw-rw-- 1 uucp dialout 4, 65 Jan 26 21:55 /dev/ttyS1
0 crw-rw-- 1 uucp dialout 4, 66 Oct 13 1997 /dev/ttyS2
0 crw-rw-- 1 uucp dialout 4, 67 Oct 13 1997 /dev/ttyS3
If there is no device with major number 4 and minor number 65, you will have to create one. Become the superuser and type:
# mknod -m 666 /dev/ttyS1 c 4 65
# chown uucp.dialout /dev/ttyS1
The various Linux distributions use slightly differing strategies for who should own the serial devices. Sometimes they will be owned by root , and other times they will be owned by another user, such as uucpin our example. Modern distributions have a group specifically for dial-out devices, and any users who are allowed to use them are added to this group.
Some people suggest making /dev/modem a symbolic link to your modem device so that casual users don't have to remember the somewhat unintuitive ttyS1 . However, you cannot use modem in one program and the real device file name in another. Their lock files would have different names and the locking mechanism wouldn't work.
RS-232 is currently the most common standard for serial communications in the PC world. It uses a number of circuits for transmitting single bits, as well as for synchronization. Additional lines may be used for signaling the presence of a carrier (used by modems) and for handshaking. Linux supports a wide variety of serial cards that use the RS-232 standard.
Hardware handshake is optional, but very useful. It allows either of the two stations to signal whether it is ready to receive more data, or if the other station should pause until the receiver is done processing the incoming data. The lines used for this are called "Clear to Send" (CTS) and "Ready to Send" (RTS), respectively, which explains the colloquial name for hardware handshake: "RTS/CTS." The other type of handshake you might be familiar with is called "XON/XOFF" handshaking. XON/XOFF uses two nominated characters, conventionally Ctrl-S and Ctrl-Q, to signal to the remote end that it should stop and start transmitting data, respectively. While this method is simple to implement and okay for use by dumb terminals, it causes great confusion when you are dealing with binary data, as you may want to transmit those characters as part of your data stream, and not have them interpreted as flow control characters. It is also somewhat slower to take effect than hardware handshake. Hardware handshake is clean, fast, and recommended in preference to XON/XOFF when you have a choice.
In the original IBM PC, the RS-232 interface was driven by a UART chip called the 8250. PCs around the time of the 486 used a newer version of the UART called the 16450. It was slightly faster than the 8250. Nearly all Pentium-based machines have been supplied with an even newer version of the UART called the 16550. Some brands (most notably internal modems equipped with the Rockwell chip set) use completely different chips that emulate the behavior of the 16550 and can be treated similarly. Linux supports all of these in its standard serial port driver. [27] Note that we are not talking about WinModem(TM) here! WinModems have very simple hardware and rely completely on the main CPU of your computer instead of dedicated hardware to do all of the hard work. If you're purchasing a modem, it is our strongest recommendation to not purchase such a modem; get a real modem. You may find Linux support for WinModems, but that makes them only a marginally more attractive solution.
The 16550 was a significant improvement over the 8250 and the 16450 because it offered a 16-byte FIFO buffer. The 16550 is actually a family of UART devices, comprising the 16550, the 16550A, and the 16550AFN (later renamed PC16550DN). The differences relate to whether the FIFO actually works; the 16550AFN is the one that is sure to work. There was also an NS16550, but its FIFO never really worked either.
The 8250 and 16450 UARTs had a simple 1-byte buffer. This means that a 16450 generates an interrupt for every character transmitted or received. Each interrupt takes a short period of time to service, and this small delay limits 16450s to a reliable maximum bit speed of about 9,600 bps in a typical ISA bus machine.
In the default configuration, the kernel checks the four standard serial ports, COM1: through COM4:. The kernel is also able to automatically detect what UART is used for each of the standard serial ports, and will make use of the enhanced FIFO buffer of the 16550, if it is available.
Using the Configuration Utilities
Now let's spend some time looking at the two most useful serial device configuration utilities: setserial and stty.
The kernel will make its best effort to correctly determine how your serial hardware is configured, but the variations on serial device configuration makes this determination difficult to achieve 100 percent reliably in practice. A good example of where this is a problem is the internal modems we talked about earlier. The UART they use has a 16-byte FIFO buffer, but it looks like a 16450 UART to the kernel device driver: unless we specifically tell the driver that this port is a 16550 device, the kernel will not make use of the extended buffer. Yet another example is that of the dumb 4-port cards that allow sharing of a single IRQ among a number of serial devices. We may have to specifically tell the kernel which IRQ port it's supposed to use, and that IRQs may be shared.
setserial was created to configure the serial driver at runtime. The setserial command is most commonly executed at boot time from a script called 0setserial on some distributions, and rc.serial on others. This script is charged with the responsibility of initializing the serial driver to accommodate any nonstandard or unusual serial hardware in the machine.
The general syntax for the setserial command is:
setserial device [ parameters
]
in which the device is one of the serial devices, such as ttyS0 .
The setserial command has a large number of parameters. The most common of these are described in Table 4.1. For information on the remainder of the parameters, you should refer to the setserial manual page.
Table 4.1: setserial Command-Line Parameters
Parameter Description |
port port_number |
Specify the I/O port address of the serial device. Port numbers should be specified in hexadecimal notation, e.g., 0x2f8. |
irq num |
Specify the interrupt request line the serial device is using. |
uart uart_type |
Specify the UART type of the serial device. Common values are 16450, 16550, etc. Setting this value to none will disable this serial device. |
fourport |
Specifying this parameter instructs the kernel serial driver that this port is one port of an AST Fourport card. |
spd_hi |
Program the UART to use a speed of 57.6 kbps when a process requests 38.4 kbps. |
spd_vhi |
Program the UART to use a speed of 115 kbps when a process requests 38.4 kbps. |
spd_normal |
Program the UART to use the default speed of 38.4 kbps when requested. This parameter is used to reverse the effect of a spd_hi or spd_vhi performed on the specified serial device. |
auto_irq |
This parameter will cause the kernel to attempt to automatically determine the IRQ of the specified device. This attempt may not be completely reliable, so it is probably better to think of this as a request for the kernel to guess the IRQ. If you know the IRQ of the device, you should specify that it use the irq parameter instead. |
autoconfig |
This parameter must be specified in conjunction with the port parameter. When this parameter is supplied, setserial instructs the kernel to attempt to automatically determine the UART type located at the supplied port address. If the auto_irq parameter is also supplied, the kernel attempts to automatically determine the IRQ, too. |
skip_test |
This parameter instructs the kernel not to bother performing the UART type test during auto-configuration. This is necessary when the UART is incorrectly detected by the kernel. |
A typical and simple rc file to configure your serial ports at boot time might look something like that shown in Example 4.1. Most Linux distributions will include something slightly more sophisticated than this one.
Читать дальше