123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- Downloaded from http://www.lafn.org/~dave/linux/Serial-Programming-HOWTO.txt
- Seems to be somewhat old, but contains useful bits for getty.c hacking
- ============================================================================
- The Linux Serial Programming HOWTO, Part 1 of 2
- By Vernon C. Hoxie
- v2.0 10 September 1999
- This document describes how to program communications with devices
- over a serial port on a Linux box.
- ______________________________________________________________________
- Table of Contents
- 1. Copyright
- 2. Introduction
- 3. Opening
- 4. Commands
- 5. Changing Baud Rates
- 6. Additional Control Calls
- 6.1 Sending a "break".
- 6.2 Hardware flow control.
- 6.3 Flushing I/O buffers.
- 7. Modem control
- 8. Process Groups
- 8.1 Sessions
- 8.2 Process Groups
- 8.3 Controlling Terminal
- 8.3.1 Get the foreground group process id.
- 8.3.2 Set the foreground process group id of a terminal.
- 8.3.3 Get process group id.
- 9. Lockfiles
- 10. Additional Information
- 11. Feedback
- ______________________________________________________________________
- 1. Copyright
- The Linux Serial-Programming-HOWTO is copyright (C) 1997 by Vernon
- Hoxie. Linux HOWTO documents may be reproduced and distributed in
- whole or in part, in any medium physical or electronic, as long as
- this copyright notice is retained on all copies. Commercial
- redistribution is allowed and encouraged; however, the author would
- like to be notified of any such distributions.
- All translations, derivative works, or aggregate works incorporating
- this Linux HOWTO document must be covered under this copyright notice.
- That is, you may not produce a derivative work from this HOWTO and
- impose additional restrictions on its distribution.
- This version is a complete rewrite of the previous Serial-Programming-
- HOWTO by Peter H. Baumann, <mailto:Peter.Baumann@dlr.de>
- 2. Introduction
- This HOWTO will attempt to give hints about how to write a program
- which needs to access a serial port. Its principal focus will be on
- the Linux implementation and what the meaning of the various library
- functions available.
- Someone asked about which of several sequences of operations was
- right. There is no absolute right way to accomplish an outcome. The
- options available are too numerous. If your sequences produces the
- desired results, then that is the right way for you. Another
- programmer may select another set of options and get the same results.
- His method is right for him.
- Neither of these methods may operate properly with some other
- implementation of UNIX. It is strange that many of the concepts which
- were implemented in the SYSV version have been dumped. Because UNIX
- was developed by AT&T and much code has been generated on those
- concepts, the AT&T version should be the standard to which others
- should emulate.
- Now the standard is POSIX.
- It was once stated that the popularity of UNIX and C was that they
- were created by programmers for programmers. Not by scholars who
- insist on purity of style in deference to results and simplicity of
- use. Not by committees with people who have diverse personal or
- proprietary agenda. Now ANSI and POSIX have strayed from those
- original clear and simply concepts.
- 3. Opening
- The various serial devices are opened just as any other file.
- Although, the fopen(3) command may be used, the plain open(2) is
- preferred. This call returns the file descriptor which is required
- for the various commands that configure the interface.
- Open(2) has the format:
- #include <fcntl.h>
- int open(char *path, int flags, [int mode]);
- In addition to the obvious O_RDWR, O_WRONLY and O_RDONLY, two
- additional flags are available. These are O_NONBLOCK and O_NOCTTY.
- Other flags listed in the open(2) manual page are not applicable to
- serial devices.
- Normally, a serial device opens in "blocking" mode. This means that
- the open() will not return until the Carrier Detect line from the port
- is active, e.g. modem, is active. When opened with the O_NONBLOCK
- flag set, the open() will return immediately regardless of the status
- of the DCD line. The "blocking" mode also affects the read() call.
- The fcntl(2) command can be used to change the O_NONBLOCK flag anytime
- after the device has been opened.
- The device driver and the data passing through it are controlled
- according to settings in the struct termios. This structure is
- defined in "/usr/include/termios.h". In the Linux tree, further
- reference is made to "/usr/include/asm/termbits.h".
- In blocking mode, a read(2) will block until data is available or a
- signal is received. It is still subject to state of the ICANON flag.
- When the termios.c_lflag ICANON bit is set, input data is collected
- into strings until a NL, EOF or EOL character is received. You can
- define these in the termios.c_cc[] array. Also, ERASE and KILL
- characters will operate on the incoming data before it is delivered to
- the user.
- In non-canonical mode, incoming data is quanitified by use of the
- c_cc[VMIN and c_cc[VTIME] values in termios.c_cc[].
- Some programmers use the select() call to detect the completion of a
- read(). This is not the best way of checking for incoming data.
- Select() is part of the SOCKETS scheme and too complex for most
- applications.
- A full explanation of the fields of the termios structure is contained
- in termios(7) of the Users Manual. A version is included in Part 2 of
- this HOWTO document.
- 4. Commands
- Changes to the struct termios are made by retrieving the current
- settings, making the desired changes and transmitting the modified
- structure back to the kernel.
- The historic means of communicating with the kernel was by use of the
- ioctl(fd, COMMAND, arg) system call. Then the purists in the
- computer industry decided that this was not genetically consistent.
- Their argument was that the argument changed its stripes. Sometimes
- it was an int, sometimes it was a pointer to int and other times it
- was a pointer to struct termios. Then there were those times it was
- empty or NULL. These variations are dependent upon the COMMAND.
- As a alternative, the tc* series of functions were concocted.
- These are:
- int tcgetattr(int filedes, struct termios *termios_p);
- int tcsetattr(int filedes, int optional_actions,
- const struct termios *termios_p);
- instead of:
- int ioctl(int filedes, int command,
- struct termios *termios_p);
- where command is TCGETS or one of TCSETS, TCSETSW or TCSETSF.
- The TCSETS command is comparable to the TCSANOW optional_action for
- the tc* version. These direct the kernel to adopt the changes
- immediately. Other pairs are:
- command optional_action Meaning
- TCSETSW TCSADRAIN Change after all output has drained.
- TCSETSF TCSAFLUSH Change after all output has drained
- then discard any input characters
- not read.
- Since the return code from either the ioctl(2) or the tcsetattr(2)
- commands only indicate that the command was processed by the kernel.
- These do not indicate whether or not the changes were actually
- accomplished. Either of these commands should be followed by a call
- to:
- ioctl(fd, TCGETS, &new_termios);
- or:
- tcgetattr(fd, &new_termios);
- A user function which makes changes to the termios structure should
- define two struct termios variables. One of these variables should
- contain the desired configuration. The other should contain a copy of
- the kernels version. Then after the desired configuration has been
- sent to the kernel, another call should be made to retrieve the
- kernels version. Then the two compared.
- Here is an example of how to add RTS/CTS flow control:
- struct termios my_termios;
- struct termios new_termios;
- tcgetattr(fd, &my_termios);
- my_termios.c_flag |= CRTSCTS;
- tcsetattr(fd, TCSANOW, &my_termios);
- tcgetattr(fd, &new_termios);
- if (memcmp(my_termios, new_termios,
- sizeof(my_termios)) != 0) {
- /* do some error handling */
- }
- 5. Changing Baud Rates
- With Linux, the baud rate can be changed using a technique similar to
- add/delete RTS/CTS.
- struct termios my_termios;
- struct termios new_termios;
- tcgetattr(fd, &my_termios);
- my_termios.c_flag &= ~CBAUD;
- my_termios.c_flag |= B19200;
- tcsetattr(fd, TCSANOW, &my_termios);
- tcgetattr(fd, &new_termios);
- if (memcmp(my_termios, new_termios,
- sizeof(my_termios)) != 0) {
- /* do some error handling */
- }
- POSIX adds another method. They define:
- speed_t cfgetispeed(const struct termios *termios_p);
- speed_t cfgetospeed(const struct termios *termios_p);
- library calls to extract the current input or output speed from the
- struct termios pointed to with *termio_p. This is a variable defined
- in the calling process. In practice, the data contained in this
- termios, should be obtained by the tcgetattr() call or an ioctl() call
- using the TCGETS command.
- The companion library calls are:
- int cfsetispeed(struct termios *termios_p, speed_t speed);
- int cfsetospeed(struct termios *termios_p, speed_t speed);
- which are used to change the value of the baud rate in the locally
- defined *termios_p. Following either of these calls, either a call to
- tcsetattr() or ioctl() with one of TCSETS, TCSETSW or TCSETSF as the
- command to transmit the change to the kernel.
- The cf* commands are preferred for portability. Some weird Unices use
- a considerably different format of termios.
- Most implementations of Linux use only the input speed for both input
- and output. These functions are defined in the application program by
- reference to <termios.h>. In reality, they are in
- /usr/include/asm/termbits.h.
- 6. Additional Control Calls
- 6.1. Sending a "break".
- int ioctl(fd, TCSBRK, int arg);
- int tcsendbreak(fd, int arg);
- Send a break: Here the action differs between the conventional
- ioctl() call and the POSIX call. For the conventional call, an arg of
- '0' sets the break control line of the UART for 0.25 seconds. For the
- POSIX command, the break line is set for arg times 0.1 seconds.
- 6.2. Hardware flow control.
- int ioctl(fd, TCXONC, int action);
- int tcflow(fd, int action);
- The action flags are:
- o TCOOFF 0 suspend output
- o TCOON 1 restart output
- o TCIOFF 2 transmit STOP character to suspend input
- o TCION 3 transmit START character to restart input
- 6.3. Flushing I/O buffers.
- int ioctl(fd, TCFLSH, queue_selector);
- int tcflush(fd, queue_selector);
- The queue_selector flags are:
- o TCIFLUSH 0 flush any data not yet read from the input buffer
- o TCOFLUSH 1 flush any data written to the output buffer but not
- yet transmitted
- o TCIOFLUSH 2 flush both buffers
- 7. Modem control
- The hardware modem control lines can be monitored or modified by the
- ioctl(2) system call. A set of comparable tc* calls apparently do not
- exist. The form of this call is:
- int ioctl(fd, COMMAND, (int *)flags);
- The COMMANDS and their action are:
- o TIOCMBIS turn on control lines depending upon which bits are set
- in flags.
- o TIOCMBIC turn off control lines depending upon which bits are
- unset in flags.
- o TIOCMGET the appropriate bits are set in flags according to the
- current status
- o TIOCMSET the state of the UART is changed according to which bits
- are set/unset in 'flags'
- The bit pattern of flags refer to the following control lines:
- o TIOCM_LE Line enable
- o TIOCM_DTR Data Terminal Ready
- o TIOCM_RTS Request to send
- o TIOCM_ST Secondary transmit
- o TIOCM_SR Secondary receive
- o TIOCM_CTS Clear to send
- o TIOCM_CAR Carrier detect
- o TIOCM_RNG Ring
- o TIOCM_DSR Data set ready
- It should be noted that some of these bits are controlled by the modem
- and the UART cannot change them but their status can be sensed by
- TIOCMGET. Also, most Personal Computers do not provide hardware for
- secondary transmit and receive.
- There are also a pair of ioctl() to monitor these lines. They are
- undocumented as far as I have learned. The commands are TIOCMIWAIT
- and TCIOGICOUNT. They also differ between versions of the Linux
- kernel.
- See the lines.c file in my "serial_suite" for an example of how these
- can be used see <ftp://scicom.alphacd.com/pub/linux/serial_suite>
- 8. Process Groups
- 8.1. Sessions
- 8.2. Process Groups
- Any newly created process inherits the Process Group of its creator.
- The Process Group leader has the same PID as PGID.
- 8.3. Controlling Terminal
- There are a series of ioctl(2) and tc*(2) calls which can be used to
- monitor or to change the process group to which the device is
- attached.
- 8.3.1. Get the foreground group process id.
- If there is no foreground group, a number not representing an existing
- process group is returned. On error, a -1 is returned and errno is
- set.
- int ioctl(fd, TIOCGPGRP, (pid_t *)pid);
- int tcgetpgrp(fd, (pid_t *)pid);
- 8.3.2. Set the foreground process group id of a terminal.
- The fd must be the controlling terminal and be associated with the
- session of the calling process.
- int ioctl(fd, TIOCSPGRP, (pid_t *)pid);
- int tcsetpgrp(fd, (pid_t *)pid);
- 8.3.3. Get process group id.
- int ioctl(fd, TIOCGPGRP, &(pid_t)pid);
- int tcgetpgrp(fd, &(pid_t)pid);
- 9. Lockfiles
- Any process which accesses a serial device should first check for the
- existence of lock file for the desired device. If such a lock lock
- file exists, this means that the device may be in use by another
- process.
- Check my "libdevlocks-x.x.tgz" at
- <ftp://scicom.alphacdc.com/pub/linux> for an example of how these lock
- files should be utilized.
- 10. Additional Information
- Check out my "serial_suite.tgz" for more information about programming
- the serial ports at <mailto:vern@zebra.alphacdc.com>. There some
- examples and some blurbs about setting up modems and comments about
- some general considerations.
- 11. Feedback
- Please send me any corrections, questions, comments, suggestions, or
- additional material. I would like to improve this HOWTO! Tell me
- exactly what you don't understand, or what could be clearer. You can
- reach me at <mailto:vern@zebra.alphacdc.com> via email. Please
- include the version number of the Serial-Programming-HOWTO when
- writing.
|