--- /dev/null
+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.
+++ /dev/null
-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.