diff options
Diffstat (limited to 'loginutils')
-rw-r--r-- | loginutils/Serial-Programming-HOWTO.txt | 424 |
1 files changed, 0 insertions, 424 deletions
diff --git a/loginutils/Serial-Programming-HOWTO.txt b/loginutils/Serial-Programming-HOWTO.txt deleted file mode 100644 index 0dfc8aa31..000000000 --- a/loginutils/Serial-Programming-HOWTO.txt +++ /dev/null @@ -1,424 +0,0 @@ -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. |