C-code Reading Serial Buffer Terminated With Lf
Serial Programming Guide for POSIX Operating Systems
5th Edition
Michael R. Sweetness
Copyright 1994-1999, All Rights Reserved.
Tabular array of Contents
Introduction
Chapter 1, Nuts of Serial Communications
- What Are Serial Communications?
- What Is RS-232?
- Point Definitions
- Asynchronous Communications
- What Are Total Duplex and Half Duplex?
- Flow Control
- What Is a Break?
- Synchronous Communications
- Accessing Serial Ports
- Serial Port Files
- Opening a Serial Port
- Writing Data to the Port
- Reading Information from the Port
- Closing a Serial Port
- The POSIX Last Interface
- Control Options
- Local Options
- Input Options
- Output Options
- Control Characters
- What Is a MODEM?
- Communicating With a MODEM
- Standard MODEM Commands
- Mutual MODEM Communication Problems
- Serial Port IOCTLs
- Getting the Control Signals
- Setting the Command Signals
- Getting the Number of Bytes Available
- Selecting Input from a Serial Port
- The SELECT Organisation Call
- Using the SELECT System Telephone call
- Using SELECT with the X Intrinsics Library
- RS-232 Pinouts
- RS-422 Pinouts
- RS-574 (IBM PC/AT) Pinouts
- SGI Pinouts
- Control Codes
Introduction
The Serial Programming Guide for POSIX Operating Systems will teach yous how to successfully, efficiently, and portably plan the serial ports on your UNIX® workstation or PC. Each chapter provides programming examples that use the POSIX (Portable Standard for UNIX) terminal control functions and should piece of work with very few modifications under IRIX®, HP-UX, SunOS®, Solaris®, Digital UNIX®, Linux®, and most other UNIX operating systems. The biggest difference betwixt operating systems that you will find is the filenames used for serial port device and lock files.
This guide is organized into the following chapters and appendices:
- Chapter one, Basics of Serial Programming
- Chapter 2, Configuring the Series Port
- Chapter iii, Talking to MODEMs
- Chapter iv, Advanced Serial Programming
- Appendix A, RS-232 Pinouts
- Appendix B, ASCII Control Codes
Chapter 1, Basics of Serial Communications
This chapter introduces series communications, RS-232 and other standards that are used on virtually computers too as how to admission a serial port from a C program.
What Are Serial Communications?
Computers transfer data (information) ane or more bits at a fourth dimension. Serial refers to the transfer of data one bit at a time. Serial communications include about network devices, keyboards, mice, MODEMs, and terminals.
When doing serial communications each word (i.e. byte or grapheme) of data you send or receive is sent one bit at a time. Each bit is either on or off. The terms you'll hear sometimes are mark for the on country and infinite for the off country.
The speed of the series data is most oftentimes expressed as $.25-per-2nd ("bps") or baudot rate ("baud"). This just represents the number of ones and zeroes that can be sent in one second. Back at the dawn of the estimator age, 300 baud was considered fast, but today computers can handle RS-232 speeds as high every bit 430,800 baud! When the baud rate exceeds 1,000, you'll usually run across the rate shown in kilo baud, or kbps (e.grand. 9.6k, 19.2k, etc). For rates to a higher place 1,000,000 that rate is shown in megabaud, or Mbps (e.k. 1.5Mbps).
When referring to series devices or ports, they are either labeled as Data Communications Equipment ("DCE") or Data Last Equipment ("DTE"). The divergence between these is simple - every signal pair, similar transmit and receive, is swapped. When connecting 2 DTE or 2 DCE interfaces together, a serial null-MODEM cablevision or adapter is used that swaps the bespeak pairs.
What Is RS-232?
RS-232 is a standard electrical interface for serial communications divers past the Electronic Industries Association ("Environmental impact assessment"). RS-232 actually comes in 3 dissimilar flavors (A, B, and C) with each one defining a different voltage range for the on and off levels. The about usually used variety is RS-232C, which defines a marker (on) fleck as a voltage betwixt -3V and -12V and a space (off) fleck as a voltage betwixt +3V and +12V. The RS-232C specification says these signals can go about 25 feet (8m) before they become unusable. You tin can usually send signals a chip further than this as long as the baud is depression enough.
Besides wires for incoming and outgoing data, in that location are others that provide timing, status, and handshaking:
| Pin | Description | Pivot | Description | Pin | Description | Pin | Description | Pin | Description |
|---|---|---|---|---|---|---|---|---|---|
| one | Globe Ground | half-dozen | DSR - Information Set Set | xi | Unassigned | 16 | Secondary RXD | 21 | Betoken Quality Detect |
| 2 | TXD - Transmitted Data | 7 | GND - Logic Ground | 12 | Secondary DCD | 17 | Receiver Clock | 22 | Band Detect |
| 3 | RXD - Received Data | eight | DCD - Information Carrier Detect | 13 | Secondary CTS | xviii | Unassigned | 23 | Data Rate Select |
| iv | RTS - Request To Send | 9 | Reserved | 14 | Secondary TXD | xix | Secondary RTS | 24 | Transmit Clock |
| 5 | CTS - Articulate To Send | 10 | Reserved | xv | Transmit Clock | twenty | DTR - Information Terminal Ready | 25 | Unassigned |
Ii standards for serial interfaces you may also see are RS-422 and RS-574. RS-422 uses lower voltages and differential signals to permit cable lengths up to virtually 1000ft (300m). RS-574 defines the nine-pin PC serial connector and voltages.
Betoken Definitions
The RS-232 standard defines some eighteen different signals for serial communications. Of these, only six are more often than not available in the UNIX environs.
GND - Logic Footing
Technically the logic ground is not a point, only without it none of the other signals will operate. Basically, the logic ground acts as a reference voltage so that the electronics know which voltages are positive or negative.
TXD - Transmitted Data
The TXD signal carries information transmitted from your workstation to the computer or device on the other end (like a MODEM). A mark voltage is interpreted as a value of 1, while a infinite voltage is interpreted as a value of 0.
RXD - Received Data
The RXD betoken carries data transmitted from the computer or device on the other end to your workstation. Like TXD, marking and space voltages are interpreted as 1 and 0, respectively.
DCD - Data Carrier Detect
The DCD point is received from the estimator or device on the other end of your serial cable. A space voltage on this signal line indicates that the computer or device is currently continued or on line. DCD is non always used or bachelor.
DTR - Information Last Ready
The DTR signal is generated by your workstation and tells the reckoner or device on the other cease that you are ready (a space voltage) or not-ready (a mark voltage). DTR is usually enabled automatically whenever yous open up the serial interface on the workstation.
CTS - Articulate To Send
The CTS betoken is received from the other cease of the serial cable. A infinite voltage indicates that is alright to send more serial data from your workstation.
CTS is normally used to regulate the flow of serial data from your workstation to the other terminate.
RTS - Request To Send
The RTS bespeak is set to the space voltage by your workstation to indicate that more data is ready to exist sent.
Like CTS, RTS helps to regulate the flow of data between your workstation and the calculator or device on the other end of the series cable. Well-nigh workstations leave this signal ready to the space voltage all the time.
Asynchronous Communications
For the figurer to understand the series data coming into it, information technology needs some way to determine where one grapheme ends and the side by side begins. This guide deals exclusively with asynchronous series data.
In asynchronous mode the series data line stays in the mark (ane) state until a character is transmitted. A start bit preceeds each character and is followed immediately by each bit in the graphic symbol, an optional parity bit, and one or more end bits. The get-go bit is always a space (0) and tells the reckoner that new serial data is bachelor. Data can be sent or received at whatsoever time, thus the proper name asynchronous.
Figure 1 - Asynchronous Data Manual
The optional parity bit is a simple sum of the data bits indicating whether or not the information contains an even or odd number of ane $.25. With fifty-fifty parity, the parity bit is 0 if there is an even number of one's in the character. With odd parity, the parity bit is 0 if in that location is an odd number of 1's in the data. You may besides hear the terms space parity, mark parity, and no parity. Space parity means that the parity bit is e'er 0, while marking parity ways the scrap is always 1. No parity ways that no parity flake is present or transmitted.
The remaining bits are called stop bits. In that location can exist 1, 1.five, or 2 stop bits between characters and they always have a value of one. Stop bits traditionally were used to give the figurer time to process the previous character, just now only serve to synchronize the receiving estimator to the incoming characters.
Asynchronous data formats are normally expressed every bit "8N1", "7E1", and so forth. These represent "viii information bits, no parity, 1 stop bit" and "7 data bits, even parity, 1 end bit" respectively.
What Are Full Duplex and Half Duplex?
Full duplex means that the calculator tin can send and receive data simultaneously - there are 2 separate data channels (one coming in, one going out).
One-half duplex means that the computer cannot send or receive data at the aforementioned fourth dimension. Ordinarily this means in that location is only a single data aqueduct to discuss. This does not mean that whatsoever of the RS-232 signals are not used. Rather, it usually means that the communications link uses some standard other than RS-232 that does not back up full duplex operation.
Flow Control
It is often necessary to regulate the menstruation of information when transferring data between ii series interfaces. This can be due to limitations in an intermediate series communications link, one of the series interfaces, or some storage media. Two methods are ordinarily used for asynchronous data.
The first method is often called "software" flow control and uses special characters to showtime (XON or DC1, 021 octal) or stop (XOFF or DC3, 023 octal) the catamenia of data. These characters are defined in the American Standard Code for Data Interchange ("ASCII"). While these codes are useful when transferring textual data, they cannot be used when transferring other types of information without special programming.
The second method is called "hardware" flow control and uses the RS-232 CTS and RTS signals instead of special characters. The receiver sets CTS to the space voltage when it is ready to receive more data and to the mark voltage when it is not set. Likewise, the sender sets RTS to the space voltage when it is ready to send more information. Because hardware flow control uses a separate prepare of signals, information technology is much faster than software period control which needs to send or receive multiple bits of information to do the same thing. CTS/RTS menstruum control is non supported by all hardware or operating systems.
What Is a Break?
Normally a receive or transmit data point stays at the mark voltage until a new graphic symbol is transferred. If the bespeak is dropped to the space voltage for a long period of fourth dimension, usually i/four to 1/2 second, and so a break condition is said to exist.
A break is sometimes used to reset a communications line or change the operating mode of communications hardware like a MODEM. Chapter 3, Talking to MODEMs covers these applications in more than depth.
Synchronous Communications
Unlike asynchronous data, synchronous data appears equally a constant stream of bits. To read the data on the line, the figurer must provide or receive a mutual bit clock so that both the sender and receiver are synchronized.
Fifty-fifty with this synchronization, the calculator must marking the beginning of the data somehow. The well-nigh common way of doing this is to utilise a data package protocol like Serial Information Link Control ("SDLC") or High-Speed Data Link Control ("HDLC").
Each protocol defines certain bit sequences to represent the kickoff and stop of a data bundle. Each also defines a chip sequence that is used when there is no data. These bit sequences allow the estimator see the showtime of a data bundle.
Because synchronous protocols do not use per-character synchronization bits they typically provide at least a 25% improvement in operation over asynchronous communications and are suitable for remote networking and configurations with more than two serial interfaces.
Despite the speed advantages of synchronous communications, most RS-232 hardware does not support it due to the extra hardware and software required.
Accessing Serial Ports
Similar all devices, UNIX provides admission to serial ports via device files. To admission a serial port you lot simply open up the corresponding device file.
Serial Port Files
Each series port on a UNIX organization has one or more than device files (files in the /dev directory) associated with information technology:
| System | Port one | Port 2 |
|---|---|---|
| IRIX® | /dev/ttyf1 | /dev/ttyf2 |
| HP-UX | /dev/tty1p0 | /dev/tty2p0 |
| Solaris®/SunOS® | /dev/ttya | /dev/ttyb |
| Linux® | /dev/ttyS0 | /dev/ttyS1 |
| Digital UNIX® | /dev/tty01 | /dev/tty02 |
Opening a Serial Port
Since a serial port is a file, the open(2) function is used to access it. The one hitch with UNIX is that device files are usually not accessable by normal users. Workarounds include changing the access permissions to the file(s) in question, running your program as the super-user (root), or making your program set-userid so that information technology runs as the owner of the device file.
For now we'll assume that the file is accessable by all users. The code to open up series port 1 on an sgi® workstation running IRIX is:
Listing 1 - Opening a serial port.
#include <stdio.h> /* Standard input/output definitions */ #include <string.h> /* String part definitions */ #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File command definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ /* * 'open_port()' - Open up series port 1. * * Returns the file descriptor on success or -1 on fault. */ int open_port(void) { int fd; /* File descriptor for the port */ fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -one) { /* * Could not open the port. */ perror("open_port: Unable to open /dev/ttyf1 - "); } else fcntl(fd, F_SETFL, 0); render (fd); } Other systems would require the corresponding device file name, just otherwise the lawmaking is the same.
Open Options
You'll notice that when we opened the device file we used 2 other flags forth with the read+write mode:
fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY); The O_NOCTTY flag tells UNIX that this programme doesn't want to exist the "decision-making last" for that port. If y'all don't specify this then whatever input (such as keyboard abort signals and and so forth) volition affect your process. Programs like getty(1M/8) employ this characteristic when starting the login procedure, but unremarkably a user program does non want this behavior.
The O_NDELAY flag tells UNIX that this program doesn't care what land the DCD signal line is in - whether the other end of the port is up and running. If y'all do not specify this flag, your process will be put to sleep until the DCD signal line is the space voltage.
Writing Data to the Port
Writing data to the port is like shooting fish in a barrel - simply use the write(two) system call to transport data it:
n = write(fd, "ATZ\r", 4); if (n < 0) fputs("write() of iv bytes failed!\due north", stderr); The write function returns the number of bytes sent or -ane if an error occurred. Usually the merely fault y'all'll encounter is EIO when a MODEM or data link drops the Data Carrier Detect (DCD) line. This status volition persist until you close the port.
Reading Information from the Port
Reading data from a port is a little trickier. When you operate the port in raw data mode, each read(2) organization call volition return however many characters are actually available in the serial input buffers. If no characters are available, the telephone call will block (wait) until characters come up in, an interval timer expires, or an error occurs. The read function can be made to return immediately by doing the following:
fcntl(fd, F_SETFL, FNDELAY);
The FNDELAY option causes the read office to return 0 if no characters are available on the port. To restore normal (blocking) beliefs, telephone call fcntl() without the FNDELAY option:
fcntl(fd, F_SETFL, 0);
This is also used subsequently opening a series port with the O_NDELAY option.
Closing a Serial Port
To shut the serial port, just utilize the close arrangement telephone call:
close(fd);
Endmost a series port will as well usually set the DTR signal low which causes about MODEMs to hang up.
Affiliate 2, Configuring the Serial Port
This chapter discusses how to configure a series port from C using the POSIX termios interface.
The POSIX Terminal Interface
Virtually systems support the POSIX last (serial) interface for irresolute parameters such as baud rate, character size, and then on. The kickoff affair you demand to do is include the file <termios.h>; this defines the terminal command structure as well as the POSIX control functions.
The two most of import POSIX functions are tcgetattr(3) and tcsetattr(3). These get and prepare terminal attributes, respectively; you provide a arrow to a termios construction that contains all of the series options available:
| Member | Clarification |
|---|---|
| c_cflag | Command options |
| c_lflag | Line options |
| c_iflag | Input options |
| c_oflag | Output options |
| c_cc | Control characters |
| c_ispeed | Input baud (new interface) |
| c_ospeed | Output baud (new interface) |
Control Options
The c_cflag member controls the baud charge per unit, number of data bits, parity, end bits, and hardware flow control. There are constants for all of the supported configurations.| Abiding | Description |
|---|---|
| CBAUD | Bit mask for baud rate |
| B0 | 0 baud (driblet DTR) |
| B50 | 50 baud |
| B75 | 75 baud |
| B110 | 110 baud |
| B134 | 134.5 baud |
| B150 | 150 baud |
| B200 | 200 baud |
| B300 | 300 baud |
| B600 | 600 baud |
| B1200 | 1200 baud |
| B1800 | 1800 baud |
| B2400 | 2400 baud |
| B4800 | 4800 baud |
| B9600 | 9600 baud |
| B19200 | 19200 baud |
| B38400 | 38400 baud |
| B57600 | 57,600 baud |
| B76800 | 76,800 baud |
| B115200 | 115,200 baud |
| EXTA | External rate clock |
| EXTB | External rate clock |
| CSIZE | Chip mask for information bits |
| CS5 | 5 data bits |
| CS6 | 6 data bits |
| CS7 | 7 data bits |
| CS8 | 8 information bits |
| CSTOPB | 2 stop bits (1 otherwise) |
| CREAD | Enable receiver |
| PARENB | Enable parity bit |
| PARODD | Use odd parity instead of even |
| HUPCL | Hangup (drop DTR) on last shut |
| CLOCAL | Local line - do not change "owner" of port |
| LOBLK | Block job control output |
| CNEW_RTSCTS CRTSCTS | Enable hardware flow command (not supported on all platforms) |
The c_cflag member contains ii options that should always exist enabled, CLOCAL and CREAD. These will ensure that your program does not become the 'possessor' of the port subject to sporatic job control and hangup signals, and also that the serial interface driver will read incoming data bytes.
The baud charge per unit constants (CBAUD, B9600, etc.) are used for older interfaces that lack the c_ispeed and c_ospeed members. See the next department for information on the POSIX functions used to gear up the baud rate.
Never initialize the c_cflag (or any other flag) member straight; you should always use the bitwise AND, OR, and NOT operators to set or clear bits in the members. Different operating system versions (and fifty-fifty patches) can and do use the bits differently, and then using the bitwise operators will prevent you from clobbering a chip flag that is needed in a newer serial driver.
Setting the Baud Rate
The baud charge per unit is stored in different places depending on the operating system. Older interfaces shop the baud rate in the c_cflag member using one of the baud rate constants in table 4, while newer implementations provide the c_ispeed and c_ospeed members that contain the actual baud rate value.
The cfsetospeed(3) and cfsetispeed(three) functions are provided to set the baud charge per unit in the termios structure regardless of the underlying operating system interface. Typically you'd utilize the following code to fix the baud rate:
Listing two - Setting the baud rate.
struct termios options; /* * Get the current options for the port... */ tcgetattr(fd, &options); /* * Fix the baud rates to 19200... */ cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); /* * Enable the receiver and set local manner... */ options.c_cflag |= (CLOCAL | CREAD); /* * Set the new options for the port... */ tcsetattr(fd, TCSANOW, &options);
The tcgetattr(3) function fills the termios structure yous provide with the current serial port configuration. After we fix the baud rates and enable local manner and serial information receipt, we select the new configuration using tcsetattr(3). The TCSANOW abiding specifies that all changes should occur immediately without waiting for output data to stop sending or input data to finish receiving. In that location are other constants to wait for input and output to finish or to flush the input and output buffers.
Most systems do not back up unlike input and output speeds, so exist sure to prepare both to the aforementioned value for maximum portability.
| Constant | Description |
|---|---|
| TCSANOW | Brand changes now without waiting for data to complete |
| TCSADRAIN | Expect until everything has been transmitted |
| TCSAFLUSH | Affluent input and output buffers and make the alter |
Setting the Character Size
Different the baud rate, there is no convienience role to prepare the character size. Instead you must do a petty bitmasking to set up things up. The character size is specified in $.25:
options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag |= CS8; /* Select eight data bits */
Setting Parity Checking
Like the character size you must manually ready the parity enable and parity type $.25. UNIX serial drivers support even, odd, and no parity bit generation. Space parity tin be false with clever coding.
- No parity (8N1):
options.c_cflag &= ~PARENB options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;
options.c_cflag |= PARENB options.c_cflag &= ~PARODD options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS7;
options.c_cflag |= PARENB options.c_cflag |= PARODD options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS7;
options.c_cflag &= ~PARENB options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;
Setting Hardware Flow Control
Some versions of UNIX support hardware flow control using the CTS (Clear To Transport) and RTS (Request To Send) signal lines. If the CNEW_RTSCTS or CRTSCTS constants are divers on your system then hardware menstruum control is probably supported. Do the following to enable hardware flow control:
options.c_cflag |= CNEW_RTSCTS; /* Also called CRTSCTS */
Similarly, to disable hardware flow command:
options.c_cflag &= ~CNEW_RTSCTS;
Local Options
The local modes member c_lflag controls how input characters are managed past the serial commuter. In general yous will configure the c_lflag fellow member for canonical or raw input.
| Constant | Description |
|---|---|
| ISIG | Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals |
| ICANON | Enable canonical input (else raw) |
| XCASE | Map uppercase \lowercase (obsolete) |
| ECHO | Enable echoing of input characters |
| ECHOE | Echo erase graphic symbol as BS-SP-BS |
| ECHOK | Echo NL after kill character |
| ECHONL | Echo NL |
| NOFLSH | Disable flushing of input buffers after interrupt or quit characters |
| IEXTEN | Enable extended functions |
| ECHOCTL | Repeat control characters as ^char and delete every bit ~? |
| ECHOPRT | Echo erased character as graphic symbol erased |
| ECHOKE | BS-SP-BS entire line on line kill |
| FLUSHO | Output being flushed |
| PENDIN | Retype pending input at next read or input char |
| TOSTOP | Ship SIGTTOU for background output |
Choosing Canonical Input
Canonical input is line-oriented. Input characters are put into a buffer which can be edited interactively by the user until a CR (carriage render) or LF (line feed) grapheme is received.
When selecting this way you lot commonly select the ICANON, ECHO, and ECHOE options:
options.c_lflag |= (ICANON | Echo | ECHOE);
Choosing Raw Input
Raw input is unprocessed. Input characters are passed through exactly as they are received, when they are received. Generally you'll deselect the ICANON, Echo, ECHOE, and ISIG options when using raw input:
options.c_lflag &= ~(ICANON | Echo | ECHOE | ISIG);
A Note Most Input Echo
Never enable input echo (Repeat, ECHOE) when sending commands to a MODEM or other computer that is echoing characters, as you will generate a feedback loop between the two series interfaces!
Input Options
The input modes member c_iflag controls any input processing that is done to characters received on the port. Similar the c_cflag field, the last value stored in c_iflag is the bitwise OR of the desired options.
| Constant | Description |
|---|---|
| INPCK | Enable parity check |
| IGNPAR | Ignore parity errors |
| PARMRK | Marker parity errors |
| ISTRIP | Strip parity bits |
| IXON | Enable software flow control (outgoing) |
| IXOFF | Enable software flow command (incoming) |
| IXANY | Allow any character to start menses again |
| IGNBRK | Ignore break condition |
| BRKINT | Send a SIGINT when a break condition is detected |
| INLCR | Map NL to CR |
| IGNCR | Ignore CR |
| ICRNL | Map CR to NL |
| IUCLC | Map uppercase to lowercase |
| IMAXBEL | Echo BEL on input line likewise long |
Setting Input Parity Options
You should enable input parity checking when you have enabled parity in the c_cflag member (PARENB). The revelant constants for input parity checking are INPCK, IGNPAR, PARMRK , and ISTRIP. More often than not you will select INPCK and ISTRIP to enable checking and stripping of the parity chip:
options.c_iflag |= (INPCK | ISTRIP);
IGNPAR is a somewhat dangerous pick that tells the serial driver to ignore parity errors and pass the incoming data through equally if no errors had occurred. This tin be useful for testing the quality of a communications link, but in full general is not used for practical reasons.
PARMRK causes parity errors to be 'marked' in the input stream using special characters. If IGNPAR is enabled, a NUL graphic symbol (000 octal) is sent to your plan before every character with a parity error. Otherwise, a DEL (177 octal) and NUL character is sent along with the bad graphic symbol.
Setting Software Menstruum Control
Software period command is enabled using the IXON, IXOFF , and IXANY constants:
options.c_iflag |= (IXON | IXOFF | IXANY);
To disable software flow control simply mask those bits:
options.c_iflag &= ~(IXON | IXOFF | IXANY);
The XON (start information) and XOFF (cease data) characters are defined in the c_cc array described below.
Output Options
The c_oflag member contains output filtering options. Like the input modes, you tin select processed or raw data output.
| Constant | Clarification |
|---|---|
| OPOST | Postprocess output (not set = raw output) |
| OLCUC | Map lowercase to uppercase |
| ONLCR | Map NL to CR-NL |
| OCRNL | Map CR to NL |
| NOCR | No CR output at column 0 |
| ONLRET | NL performs CR function |
| OFILL | Use fill characters for delay |
| OFDEL | Fill character is DEL |
| NLDLY | Mask for filibuster time needed between lines |
| NL0 | No filibuster for NLs |
| NL1 | Delay further output after newline for 100 milliseconds |
| CRDLY | Mask for delay fourth dimension needed to return carriage to left column |
| CR0 | No filibuster for CRs |
| CR1 | Delay later on CRs depending on electric current column position |
| CR2 | Delay 100 milliseconds afterwards sending CRs |
| CR3 | Delay 150 milliseconds after sending CRs |
| TABDLY | Mask for delay time needed subsequently TABs |
| TAB0 | No delay for TABs |
| TAB1 | Delay after TABs depending on current column position |
| TAB2 | Delay 100 milliseconds after sending TABs |
| TAB3 | Aggrandize TAB characters to spaces |
| BSDLY | Mask for delay time needed after BSs |
| BS0 | No delay for BSs |
| BS1 | Delay fifty milliseconds afterwards sending BSs |
| VTDLY | Mask for delay fourth dimension needed after VTs |
| VT0 | No delay for VTs |
| VT1 | Delay 2 seconds after sending VTs |
| FFDLY | Mask for delay fourth dimension needed afterwards FFs |
| FF0 | No delay for FFs |
| FF1 | Delay 2 seconds after sending FFs |
Choosing Processed Output
Processed output is selected by setting the OPOST selection in the c_oflag fellow member:
options.c_oflag |= OPOST;
Of all the dissimilar options, you will only probably use the ONLCR option which maps newlines into CR-LF pairs. The rest of the output options are primarily historic and engagement back to the time when line printers and terminals could not keep up with the serial information stream!
Choosing Raw Output
Raw output is selected by resetting the OPOST option in the c_oflag member:
options.c_oflag &= ~OPOST;
When the OPOST pick is disabled, all other option $.25 in c_oflag are ignored.
Control Characters
The c_cc character array contains control character definitions also equally timeout parameters. Constants are defined for every element of this array.
| Constant | Description | Key |
|---|---|---|
| VINTR | Interrupt | CTRL-C |
| VQUIT | Quit | CTRL-Z |
| VERASE | Erase | Backspace (BS) |
| VKILL | Impale-line | CTRL-U |
| VEOF | Terminate-of-file | CTRL-D |
| VEOL | End-of-line | Carriage return (CR) |
| VEOL2 | 2d end-of-line | Line feed (LF) |
| VMIN | Minimum number of characters to read | |
| VTIME | Fourth dimension to look for information (tenths of seconds) |
Setting Software Menses Control Characters
The VSTART and VSTOP elements of the c_cc array contain the characters used for software catamenia control. Normally they should exist prepare to DC1 (021 octal) and DC3 (023 octal) which represent the ASCII standard XON and XOFF characters.
Setting Read Timeouts
UNIX serial interface drivers provide the ability to specify character and packet timeouts. 2 elements of the c_cc array are used for timeouts: VMIN and VTIME. Timeouts are ignored in canonical input style or when the NDELAY pick is set on the file via open up or fcntl.
VMIN specifies the minimum number of characters to read. If it is ready to 0, then the VTIME value specifies the time to wait for every character read. Annotation that this does non mean that a read call for N bytes will look for N characters to come in. Rather, the timeout volition employ to the first graphic symbol and the read call will return the number of characters immediately available (upwards to the number you request).
If VMIN is non-zero, VTIME specifies the fourth dimension to expect for the first grapheme read. If a character is read within the time given, any read volition block (wait) until all VMIN characters are read. That is, once the first character is read, the serial interface driver expects to receive an entire packet of characters (VMIN bytes total). If no grapheme is read within the fourth dimension allowed, and then the telephone call to read returns 0. This method allows you to tell the series driver you need exactly N bytes and whatever read call will render 0 or N bytes. Notwithstanding, the timeout merely applies to the first graphic symbol read, so if for some reason the driver misses ane character inside the North byte packet and then the read telephone call could block forever waiting for additional input characters.
VTIME specifies the amount of time to wait for incoming characters in tenths of seconds. If VTIME is set to 0 (the default), reads will block (look) indefinitely unless the NDELAY option is attack the port with open or fcntl.
Chapter three, MODEM Communications
This chapter covers the basics of dialup telephone Modulator/Demodulator (MODEM) communications. Examples are provided for MODEMs that employ the defacto standard "AT" command set.
What Is a MODEM?
MODEMs are devices that modulate serial data into frequencies that can be transferred over an analog data link such every bit a phone line or cable Television set connection. A standard telephone MODEM converts serial data into tones that tin be passed over the phone lines; considering of the speed and complication of the conversion these tones sound more like loud screeching if you listen to them.
Telephone MODEMs are available today that can transfer data beyond a telephone line at nearly 53,000 bits per second, or 53kbps. In addition, most MODEMs apply information compression technology that tin increase the bit charge per unit to well over 100kbps on some types of data.
Communicating With a MODEM
The showtime stride in communicating with a MODEM is to open and configure the port for raw input:
Listing 3 - Configuring the port for raw input.
int fd; struct termios options; /* open the port */ fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY); fcntl(fd, F_SETFL, 0); /* become the current options */ tcgetattr(fd, &options); /* set raw input, one 2d timeout */ options.c_cflag |= (CLOCAL | CREAD); options.c_lflag &= ~(ICANON | Echo | ECHOE | ISIG); options.c_oflag &= ~OPOST; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = ten; /* gear up the options */ tcsetattr(fd, TCSANOW, &options); Next you need to establish communications with the MODEM. The all-time way to do this is by sending the "AT" control to the MODEM. This also allows smart MODEMs to observe the baud you are using. When the MODEM is continued correctly and powered on it will respond with the response "OK".
Listing iv - Initializing the MODEM.
int /* O - 0 = MODEM ok, -i = MODEM bad */ init_modem(int fd) /* I - Serial port file */ { char buffer[255]; /* Input buffer */ char *bufptr; /* Electric current char in buffer */ int nbytes; /* Number of bytes read */ int tries; /* Number of tries then far */ for (tries = 0; tries < three; tries ++) { /* transport an AT command followed by a CR */ if (write(fd, "AT\r", 3) < 3) continue; /* read characters into our string buffer until we get a CR or NL */ bufptr = buffer; while ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - one)) > 0) { bufptr += nbytes; if (bufptr[-1] == '\northward' || bufptr[-one] == '\r') break; } /* nul terminate the string and see if we got an OK response */ *bufptr = '\0'; if (strncmp(buffer, "OK", ii) == 0) return (0); } return (-1); } Standard MODEM Commands
Most MODEMs support the "AT" control set, and so called because each control starts with the "AT" characters. Each control is sent with the "AT" characters starting in the first column followed by the specific command and a carriage return (CR, 015 octal). After processing the command the MODEM will reply with one of several textual messages depending on the command.
ATD - Dial A Number
The ATD command dials the specified number. In addition to numbers and dashes you lot can specify tone ("T") or pulse ("P") dialing, pause for one second (","), and wait for a dialtone ("W"):
ATDT 555-1212 ATDT 18008008008W1234,1,1234 ATD T555-1212WP1234
The MODEM will reply with one of the post-obit messages:
NO DIALTONE Decorated NO CARRIER CONNECT CONNECT baud
ATH - Hang Up
The ATH command causes the MODEM to hang upward. Since the MODEM must be in "control" manner you probably won't use it during a normal phone call.
Most MODEMs will also hang upward if DTR is dropped; you lot can do this past setting the baud to 0 for at least i second. Dropping DTR too returns the MODEM to control mode.
Afterwards a successful hang upwardly the MODEM will respond with "NO CARRIER". If the MODEM is still connected the "CONNECT" or "CONNECT baud" message will be sent.
ATZ - Reset MODEM
The ATZ control resets the MODEM. The MODEM will respond with the cord "OK".Common MODEM Communication Problems
First and foremost, don't forget to disable input echoing. Input echoing volition cause a feedback loop between the MODEM and computer.
2d, when sending MODEM commands you must cease them with a railroad vehicle render (CR) and not a newline (NL). The C character abiding for CR is "\r".
Finally, when dealing with a MODEM make sure yous use a baud that the MODEM supports. While many MODEMs do auto-baud detection, some have limits (xix.2kbps is mutual) that you lot must observe.
Chapter 4, Advanced Series Programming
This chapter covers advanced serial programming techniques using the ioctl(2) and select(ii) organization calls.
Serial Port IOCTLs
In Affiliate two, Configuring the Series Port we used the tcgetattr and tcsetattr functions to configure the serial port. Under UNIX these functions use the ioctl(2) system call to do their magic.
The ioctl system call takes 3 arguments:
int ioctl(int fd, int request, ...);
The fd argument specifies the series port file descriptor. The request argument is a constant defined in the <termios.h> header file and is typically i of the following:
| Request | Description | POSIX Function |
|---|---|---|
| TCGETS | Gets the current serial port settings. | tcgetattr |
| TCSETS | Sets the series port settings immediately. | tcsetattr(fd, TCSANOW, &options) |
| TCSETSF | Sets the series port settings after flushing the input and output buffers. | tcsetattr(fd, TCSANOW, &options) |
| TCSETSW | Sets the series port settings afterwards allowing the input and output buffers to bleed/empty. | tcsetattr(fd, TCSANOW, &options) |
| TCSBRK | Sends a suspension for the given time. | tcsendbreak, tcdrain |
| TCXONC | Controls software flow control. | tcflow |
| TCFLSH | Flushes the input and/or output queue. | tcflush |
| TIOCMGET | Returns the state of the "MODEM" bits. | None |
| TIOCMSET | Sets the state of the "MODEM" $.25. | None |
| FIONREAD | Returns the number of bytes in the input buffer. | None |
Getting the Control Signals
The TIOCMGET ioctl gets the electric current "MODEM" status bits, which consist of all of the RS-232 indicate lines except RXD and TXD:
| Constant | Description |
|---|---|
| TIOCM_LE | DSR (information ready ready/line enable) |
| TIOCM_DTR | DTR (data terminal ready) |
| TIOCM_RTS | RTS (asking to send) |
| TIOCM_ST | Secondary TXD (transmit) |
| TIOCM_SR | Secondary RXD (receive) |
| TIOCM_CTS | CTS (clear to send) |
| TIOCM_CAR | DCD (data carrier detect) |
| TIOCM_CD | Synonym for TIOCM_CAR |
| TIOCM_RNG | RNG (ring) |
| TIOCM_RI | Synonym for TIOCM_RNG |
| TIOCM_DSR | DSR (data set ready) |
To get the status bits, telephone call ioctl with a pointer to an integer to hold the bits:
Listing 5 - Getting the MODEM status bits.
#include <unistd.h> #include <termios.h> int fd; int status; ioctl(fd, TIOCMGET, &status);
Setting the Control Signals
The TIOCMSET ioctl sets the "MODEM" condition bits divers above. To drop the DTR signal you can practice:
Listing six - Dropping DTR with the TIOCMSET ioctl.
#include <unistd.h> #include <termios.h> int fd; int status; ioctl(fd, TIOCMGET, &status); status &= ~TIOCM_DTR; ioctl(fd, TIOCMSET, status);
The bits that can be set depend on the operating system, driver, and modes in apply. Consult your operating system documentation for more information.
Getting the Number of Bytes Available
The FIONREAD ioctl gets the number of bytes in the serial port input buffer. As with TIOCMGET yous pass in a pointer to an integer to hold the number of bytes:
Listing vii - Getting the number of bytes in the input buffer.
#include <unistd.h> #include <termios.h> int fd; int bytes; ioctl(fd, FIONREAD, &bytes);
This can be useful when polling a serial port for data, as your program can determine the number of bytes in the input buffer before attempting a read.
Selecting Input from a Serial Port
While simple applications can poll or expect on information coming from the serial port, near applications are non simple and demand to handle input from multiple sources.
UNIX provides this capability through the select(2) system telephone call. This system call allows your program to check for input, output, or mistake weather on 1 or more file descriptors. The file descriptors tin point to serial ports, regular files, other devices, pipes, or sockets. Yous can poll to check for pending input, wait for input indefinitely, or timeout later a specific amount of fourth dimension, making the select system call extremely flexible.
Most GUI Toolkits provide an interface to select; we will discuss the X Intrinsics ("Xt") library later in this affiliate.
The SELECT System Call
The select organization call accepts 5 arguments:
int select(int max_fd, fd_set *input, fd_set *output, fd_set *error, struct timeval *timeout);
The max_fd statement specifies the highest numbered file descriptor in the input, output, and fault sets. The input, output, and error arguments specify sets of file descriptors for pending input, output, or error conditions; specify NULL to disable monitoring for the corresponding condition. These sets are initialized using three macros:
FD_ZERO(fd_set); FD_SET(fd, fd_set); FD_CLR(fd, fd_set);
The FD_ZERO macro clears the set entirely. The FD_SET and FD_CLR macros add and remove a file descriptor from the ready, respectively.
The timeout argument specifies a timeout value which consists of seconds (timeout.tv_sec) and microseconds (timeout.tv_usec ). To poll ane or more file descriptors, fix the seconds and microseconds to zippo. To expect indefinitely specify Nil for the timeout pointer.
The select organisation call returns the number of file descriptors that have a awaiting status, or -one if there was an mistake.
Using the SELECT System Call
Suppose we are reading data from a serial port and a socket. We desire to check for input from either file descriptor, but desire to notify the user if no information is seen inside 10 seconds. To practice this we'll need to utilize the select organization call:
Listing eight - Using SELECT to procedure input from more than than ane source.
#include <unistd.h> #include <sys/types.h> #include <sys/fourth dimension.h> #include <sys/select.h> int n; int socket; int fd; int max_fd; fd_set input; struct timeval timeout; /* Initialize the input set */ FD_ZERO(input); FD_SET(fd, input); FD_SET(socket, input); max_fd = (socket > fd ? socket : fd) + 1; /* Initialize the timeout structure */ timeout.tv_sec = 10; timeout.tv_usec = 0; /* Practice the select */ northward = select(max_fd, Goose egg, Goose egg, ; /* See if there was an error */ if (n 0) perror("select failed"); else if (northward == 0) puts("TIMEOUT"); else { /* We have input */ if (FD_ISSET(fd, input)) process_fd(); if (FD_ISSET(socket, input)) process_socket(); } You'll discover that nosotros outset check the return value of the select system call. Values of 0 and -i yield the appropriate alert and fault messages. Values greater than 0 hateful that we have data pending on ane or more than file descriptors.
To decide which file descriptor(s) have pending input, we utilize the FD_ISSET macro to exam the input set for each file descriptor. If the file descriptor flag is set then the status exists (input pending in this case) and we need to do something.
Using SELECT with the X Intrinsics Library
The X Intrinsics library provides an interface to the select system call via the XtAppAddInput(3x) and XtAppRemoveInput(3x) functions:
int XtAppAddInput(XtAppContext context, int fd, int mask, XtInputProc proc, XtPointer data); void XtAppRemoveInput(XtAppContext context, int input);
The select system call is used internally to implement timeouts, work procedures, and cheque for input from the X server. These functions can be used with whatever Xt-based toolkit including Xaw, Lesstif, and Motif.
The proc argument to XtAppAddInput specifies the part to call when the selected status (e.g. input available) exists on the file descriptor. In the previous example you could specify the process_fd or process_socket functions.
Because Xt limits your access to the select system telephone call, you'll need to implement timeouts through some other machinery, probably via XtAppAddTimeout(3x).
Appendix A, Pinouts
This appendix provides pinout information for many of the mutual serial ports yous will notice.
RS-232 Pinouts
RS-232 comes in 3 flavors (A, B, C) and uses a 25-pin D-Sub connector:
Figure two - RS-232 Connector
| Pin | Clarification | Pivot | Description |
|---|---|---|---|
| one | Globe Footing | 14 | Secondary TXD |
| 2 | TXD - Transmitted Data | xv | Transmit Clock |
| three | RXD - Received Information | xvi | Secondary RXD |
| 4 | RTS - Asking To Send | 17 | Receiver Clock |
| five | CTS - Clear To Transport | 18 | Unassigned |
| six | DSR - Data Set Ready | 19 | Secondary RTS |
| 7 | GND - Logic Ground | 20 | DTR - Data Concluding Gear up |
| viii | DCD - Data Carrier Detect | 21 | Point Quality Detect |
| 9 | Reserved | 22 | Ring Detect |
| 10 | Reserved | 23 | Data Rate Select |
| 11 | Unassigned | 24 | Transmit Clock |
| 12 | Secondary DCD | 25 | Unassigned |
| xiii | Secondary CTS |
RS-422 Pinouts
RS-422 besides uses a 25-pin D-Sub connector, merely with differential signals:
Effigy 3 - RS-422 Connector
| Pin | Description | Pin | Description |
|---|---|---|---|
| one | Earth Ground | 14 | TXD+ |
| 2 | TXD- - Transmitted Data | 15 | Transmit Clock- |
| iii | RXD- - Received Information | sixteen | RXD+ |
| 4 | RTS- - Request To Send | 17 | Receiver Clock- |
| 5 | CTS- - Articulate To Ship | eighteen | Unassigned |
| vi | DSR - Data Set Ready | 19 | RTS+ |
| 7 | GND - Logic Ground | 20 | DTR- - Data Terminal Ready |
| viii | DCD- - Data Carrier Detect | 21 | Signal Quality Detect |
| ix | Reserved | 22 | Unassigned |
| 10 | Reserved | 23 | DTR+ |
| xi | Unassigned | 24 | Transmit Clock+ |
| 12 | DCD+ | 25 | Receiver Clock+ |
| 13 | CTS+ |
RS-574 (IBM PC/AT) Pinouts
The RS-574 interface is used exclusively past PC manufacturers and uses a 9-pin male D-Sub connector:
Figure 4 - RS-574 Connector
| Pin | Description | Pin | Description |
|---|---|---|---|
| ane | DCD - Data Carrier Find | 6 | Data Set up Fix |
| two | RXD - Received Data | vii | RTS - Request To Send |
| 3 | TXD - Transmitted Data | 8 | CTS - Clear To Send |
| 4 | DTR - Data Last Ready | 9 | Band Detect |
| 5 | GND - Logic Footing |
SGI Pinouts
Older SGI equipment uses a 9-pin female D-Sub connector. Unlike RS-574, the SGI pinouts nearly friction match those of RS-232:
Figure v - SGI 9-Pin Connector
| Pivot | Description | Pivot | Description |
|---|---|---|---|
| 1 | Earth Ground | half-dozen | DSR - Information Set Ready |
| 2 | TXD - Transmitted Data | seven | GND - Logic Ground |
| 3 | RXD - Received Data | eight | DCD - Data Carrier Observe |
| 4 | RTS - Request To Ship | 9 | DTR - Data Terminal Fix |
| 5 | CTS - Articulate To Ship |
The SGI Indigo, Indigo2, and Indy workstations use the Apple tree 8-pin MiniDIN connector for their series ports:
Figure 6 - SGI viii-Pin Connector
| Pin | Description | Pin | Clarification |
|---|---|---|---|
| 1 | DTR - Data Terminal Gear up | 5 | RXD - Received Data |
| 2 | CTS - Clear To Transport | 6 | RTS - Asking To Ship |
| 3 | TXD - Transmitted Information | vii | DCD - Data Carrier Discover |
| four | GND - Logic Footing | 8 | GND - Logic Ground |
Appendix B, ASCII Control Codes
This chapter lists the ASCII control codes and their names.
Control Codes
The post-obit ASCII characters are used for control purposes:| Name | Binary | Octal | Decimal | Hexadecimal |
|---|---|---|---|---|
| NUL | 00000000 | 000 | 0 | 00 |
| SOH | 00000001 | 001 | 1 | 01 |
| STX | 00000010 | 002 | 2 | 02 |
| ETX | 00000011 | 003 | 3 | 03 |
| EOT | 00000100 | 004 | 4 | 04 |
| ENQ | 00000101 | 005 | five | 05 |
| ACK | 00000110 | 006 | 6 | 06 |
| BEL | 00000111 | 007 | 7 | 07 |
| BS | 00001000 | 010 | 8 | 08 |
| HT | 00001001 | 011 | 9 | 09 |
| NL | 00001010 | 012 | 10 | 0A |
| VT | 00001011 | 013 | 11 | 0B |
| NP, FF | 00001100 | 014 | 12 | 0C |
| CR | 00001101 | 015 | 13 | 0D |
| SO | 00001110 | 016 | 14 | 0E |
| SI | 00001111 | 017 | 15 | 0F |
| DLE | 00010000 | 020 | 16 | x |
| XON, DC1 | 00010001 | 021 | 17 | 11 |
| DC2 | 00010010 | 022 | 18 | 12 |
| XOFF, DC3 | 00010011 | 023 | nineteen | 13 |
| DC4 | 00010100 | 024 | 20 | fourteen |
| NAK | 00010101 | 025 | 21 | 15 |
| SYN | 00010110 | 026 | 22 | 16 |
| ETB | 00010111 | 027 | 23 | 17 |
| Can | 00011000 | 030 | 24 | 18 |
| EM | 00011001 | 031 | 25 | 19 |
| SUB | 00011010 | 032 | 26 | 1A |
| ESC | 00011011 | 033 | 27 | 1B |
| FS | 00011100 | 034 | 28 | 1C |
| GS | 00011101 | 035 | 29 | 1D |
| RS | 00011110 | 036 | 30 | 1E |
| United states of america | 00011111 | 037 | 31 | 1F |
thorntongracts1957.blogspot.com
Source: https://www.cmrr.umn.edu/~strupp/serial.html
0 Response to "C-code Reading Serial Buffer Terminated With Lf"
Post a Comment