Serial Programming Guide
for
POSIX Operating Systems
POSIX操作系统串行编程指南
5th Edition, 3rd Revision
Copyright 1994-2003 by Michael R. Sweet
Translated by Cedar Peng ( 翻译 彭雪松 )
-->
允许拷贝,分发或在GNU自由文档许可(Version 1.2 或任何更新的由自由软件基金会发布的版本)的条件下的修改,不可有任何章节的变化,额外的开头和结尾文字。一份许可包含在 附录 C, GNU自由文档许可.
目录
介绍
POSIX 操作系统串行编程指南将教会你如何成功、有效和可移植地在你的UNIX?工作站或PC上编程。 每章提供的编程样例使用POSIX (UNIX可移植标准)终端控制函数,少量修改就可以运行于IRIX®, HP-UX, SunOS®, Solaris®, Digital UNIX®, Linux®, 和许多其它的UNIX操作系统。 你将发现在不同操作系统之间的最大差别是串口设备和锁定文件的名字。
许可
在GNU自由文档许可(版本1.2或更新的,由自由软件基金发布的版本)的条件下,允许复制、分发或修改这个文档;不能改变章节,不能有开头和结尾的附加文本。在 附录C,GNU自由文档许可 中有一份许可复制,作为参考。
组织
这篇指南由以下章节和附录组成:
第一章,串行通讯基础
这章介绍了串行通讯,RS-232和其它一些在计算机上广泛使用的标准,同时还有如何从C程序访问串口的内容。
什么是串行通讯?
计算机一次传输一或多位的信息(数据)。串行是指一次传输一位数据。串行通讯包括了大多数的网络设备、键盘、 麦克风,调制解调器和终端。当进行串行通讯时,你传送或接受的每个字(例如:字节或字符)是以每次一位传输的。 每位或者为on 或者 off。有时你也能听到以mark 表示 on 状态和 space 表示 off 状态。
串行数据的速度常表示为比特每秒 ("bps") 或波特率 ("波特")。这只是用于表示每秒能够传送的1和0的数量。追溯到计算机时代的早期,300波特被认为是很快的速度,但今天的计算机能够控制RS-232 速度高达430,800波特!当波特率超过1,000,你通常将看到速度被表示为千波特,或kbps (例如9.6k, 19.2k等等)。对于超过1,000,000的速度表示为兆波特,或者Mbps (例如1.5Mbps)。
当提及串行设备或端口的时候,他们被表明数据通讯设备 ("DCE")或者数据终端设备 ("DTE")。 这之间的差别很简单每对信号,例如传送和接受,都需要交换。当连接两个DTE或两个DCE接口到一起的时候,需要使用一 个串行null-MODEM 缆线或适配卡来交换信号对。
什么是 RS-232?
RS-232一标准的串行通讯电气接口,由 Electronic Industries Association ("EIA")定 义。RS-232实际分为三部分(A, B和C),每部分都定义了不同的 on 与 off 间的电压等级。最为常用的是RS-232C,它定义mark (on) 一位电压在-3V到-12V之间和space (off)一位在电压+3V到 +12V之间。 RS-232C定义这些信号可以传输达25英尺 (8米)有效。只要波特率足够低,你通常能够传送更长的距离。
除了输入和输出数据的引线,还有提供时间,状态和握手信号的引线:
Pin | 描述 | Pin | 描述 | Pin | 描述 | Pin | 描述 | Pin | 描述 |
---|---|---|---|---|---|---|---|---|---|
1 | Earth Ground | 6 | DSR - Data Set Ready | 11 | 未定义 | 16 | Secondary RXD | 21 | Signal Quality Detect |
2 | TXD - Transmitted Data | 7 | GND - Logic Ground | 12 | Secondary DCD | 17 | Receiver Clock | 22 | Ring Detect |
3 | RXD - Received Data | 8 | DCD - Data Carrier Detect | 13 | Secondary CTS | 18 | 未定义 | 23 | Data Rate Select |
4 | RTS - Request To Send | 9 | Reserved | 14 | Secondary TXD | 19 | Secondary RTS | 24 | Transmit Clock |
5 | CTS - Clear To Send | 10 | Reserved | 15 | Transmit Clock | 20 | DTR - Data Terminal Ready | 25 | 未定义 |
其它两个你可能也看到过的串行接口标准是RS-422和RS-574。RS-422使用低电压和微分信号, 允许线缆长度到 1000英尺 (300米)。RS-574定义了9-pin PC串行接口和电压。
信号定义
RS-232标准定义了18种不同的串行通讯信号。当然,在UNIX环境下只有6种。
GND - Logic Ground 逻辑地
学术上而言,逻辑地不是个信号,但没有它,其它信号都不能工作。简而言之,逻辑地作为参考电压, 从而使电子器件知道某个电压是正或负。
TXD - Transmitted Data 传送数据
TXD信号传送数据从你的工作站到计算机或在另一端的设备(例如MODEM)。一个mark电压被解释为1,与 此同时一space电压被解释为0。
RXD - Received Data 接受数据
RXD信号传送数据从计算机或另一端的设备到你的工作站。类似TXD,mark和space电压相应地被解释为1和0。
DCD - Data Carrier Detect 载波侦听
DCD信号接受你的串行电缆另一头的计算机或其它设备信号。一个space电压表示计算机或设备当前连接着或在线。DCD并不总可用或存在。
DTR - Data Terminal Ready 数据终端准备好
DTR信号由你的工作站产生,告诉另一端的计算机或设备你准备好了 (一个space电压) 或者没有 (一个mark电压)。当你在工作站上打开串行接口时,DTR总是自动有效。
CTS - Clear To Send 允许发送
CTS信号接受自串行缆线另一端。一个space电压表明可以从你的工作站发送更多的串行数据。
CTS通常被用作控制从你的工作站发往另一端的串行数据。
RTS - Request To Send 要求发送
RTS信号被你的工作站设置为 space 电压表明有更多的数据等待传送。
类似 CTS,RTS帮助控制你的工作站和另一端的计算机或设备间的数据流。多数工作站始终保持这个信号为space电压。
异步通讯
为使计算机理解进入它的串行数据,它需要一些途径决定那里是字符的开始和结束。本指南仅讨论异步串行数据。
在异步模式下,串行数据线保持在mark (1)状态,直到有字符传送。一位起始 start 位,字符内容的每一位,一位可选的校验位,以及一位或一位半的终止位。起始位始终是一个 space (0),从而告诉计算机新的串行数据到来。数据能够在任何时候传送或接受,所以称做异步。
图 1 -- 异步数据通讯
可选的校验是一个简单数据位的加和,表明了数据位包含偶数或奇数个1。如果是偶校验, 当在字符中的1是偶数个数时,校验位为0。如果是奇校验,当字符中的1是奇数个时,校验位为0。你可能也听说过space校验, mark校验, 和无校验。Space校验意味着校验位始终为0,而mark校验意味着校验位始终为1。无校验意味校验不存在或不传输。
余下的被称为停止位。这可以是1, 1.5, 或2位停止位在字符之间,始终是1。停止位原先是用来给计算机时间处理前面的字符的,但现在只是用来同步计算机和接收字符。
异步数据格式通常表示为"8N1", "7E1",诸如此类。它们相应地表示"8位数据,无校验,1位停止"和"7位数据,偶校验,1位停止"。
什么是全双工与半双工?
全双工 表明计算机能够同时接受和发送数据 - 有两个分离的数据通道(一个输入,一个输出)。
半双工 表明计算机不能同时接受和发送数据。通常这意味着只有一个数据通道用来通讯。这并不意味着一些 RS-232信号没有使用。而通常是表明通讯链路使用了不同于RS-232的标准,而它们不支持全双工操作。
流控制
通常在两个串口间传送数据时,需要控制数据流。这可能是由于通讯连接媒介、一个串行接口、或某些存储介质的限制。两种方法通常用于异步数据。
第一个方法叫作"软件"流控制,使用特殊字符开始 (XON or DC1, 021 octal) 或停止 (XOFF or DC3, 023 octal) 数据流。这些字符由 American Standard Code for Information Interchange ("ASCII")定义。虽然这些代码在传送文本信息时十分有用,但没有特殊的编程手段,在传输其它类型信息的时候就不能使用了。
第二个方法叫做"硬件"流控制,使用RS-232 CTS 和RTS信号代替特殊字符。当准备好接受更多的数据后,接受方设置CTS为space电压;而设置为mark电压,表示没有准备好。同样的,准备好发送更 多数据后,发送方将RTS设置为 space电压。因为硬件流控制使用独立的信号,所以同样情况下,它要比需要传送更多位信息的软件流控制快许多。 CTS/RTS流控制并不被所有的硬件或操作系统支持。
什么是中断?
N正常的一个接受或发送数据信号保持在mark电压知道一个新的字符被传送。如果信号掉到space电压一段较长时间,通常是1/4到1/2秒,就说出现了个中断。
中断有时是用于重置通讯线或改变通讯硬件的模式,例如MODEM.第三章,MODEM通讯更为详细地讨论了这些。
同步通讯
不同于异步数据,同步数据表现为连续数据流。为在线读取数据,计算机必须提供或接受一比特同步时钟,从而 使接受和发送同步。
即便是同步情况下,计算机仍然必须标明数据的开始。最通常的做法是使用数据包协议,例如 串行 Data Link Control("SDLC")或 High-Speed Data Link Control ("HDLC")。
每个协议都定义了表示数据包开始和结束的一定比特序列。且都定义了没有数据时的比特序列。这些比特序列使 得计算机能够看到数据包的起始。
因为同步协议不使用每字符的同步位,它们通常提供比异步通讯至少高25%的效率,适合于在两个以上的串行接口 环境下,远距离网络操作与配置。
尽管同步通讯的速度优势,多数RS-232硬件仍不支持,主要是由于额外的硬件和软件需求。
访问串行端口
象所有的设备一样,UNIX提供设备文件以访问端口。要访问一个串行端口,你只要简单地打开相应的设备文件。
串行端口文件
每个串行端口在UNIX系统上有一个或多个设备文件 (文件在/dev目录下)相关联:
系统 | 端口 1 | 端口 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 |
打开串行端口
由于串行端口是一个文件, open(2) 函数正是用来访问它的。存在的阻碍是UNIX下设备文件经常不允许普通用户访问。 工作的范围包括改变有疑问的文件访问许可,以超级用户(root)运行你的程序, 或使你的程序设置userid,从而它能以设备文件的拥有者运行(由于显著的安全性问题,不建议用...)
现在我们假设文件能够被所有的用户访问。 列表1 表示了在运行Linux的PC上打开串行端口一的例子。
#include <stdio.h> /* Standard input/output definitions */ #include <string.h> /* String function definitions */ #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ /* * 'open_port()' - Open Serial port 1. * * Returns the file descriptor on success or -1 on error. */ int open_port(void) { int fd; /* File descriptor for the port */ fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { /* * Could not open the 端口. */ perror("open_端口: Unable to open /dev/ttyS0 - "); } else fcntl(fd, F_SETFL, 0); return (fd); }
其它系统可能需要不同的设备文件名,然而代码是一样的。
Open 选项
你将注意到我们打开设备文件时,除了读写模式外,还使用了两个其它的标志:
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
O_NOCTTY 标志告诉UNIX,该程序不想成为那个端口的"控制终端"。如果你不指明这个,任何输入(例如键盘中断信号, 诸如此类)都会影响你的进程。象getty(1M/8) 之类的程序在启动登录进程时,设置这一特性,但通常用户的程序不想有这种行为。
O_NDELAY 标志告诉UNIX,该程序不关心DCD信号的输入状态 - 即无论另一端端口是否启用和运行。如果你不指明这个标志, 你的进程将休眠,直到DCD信号线是space电压。
写数据到端口
写数据到端口是简单的 -- 只需要使用 write(2) 系统呼叫去传送数据:
n = write(fd, "ATZ/r", 4); if (n < 0) fputs("write() of 4 bytes failed!/n", stderr);
write 函数返回发送的字节号 -- 或1如果发现了任何错误。通常唯一的错误你可能运行进入是 EIO , 即当MODEM或数据链路丢失Carrier Detect (DCD) 线。该条件允许你保持直到端口关闭。
从端口读数据端口
从端口读取数据有一点小骗术。当你以行数据模式操作端口,每个 read(2) 系统调用都会返回, 而不论多少字符实际存在于串行输入缓冲中。 如果没有字符存在,调用将阻塞(等待)直到有字符进入,或超时,或错误出现。read方法能够用以下方法获得立即的返回:
fcntl(fd, F_SETFL, FNDELAY);
当端口没有接受到字符时,FNDELAY 项使得 read 函数返回0。要实现标准的(阻塞)行为,调用 fcntl() 而不带FNDELAY 项:
fcntl(fd, F_SETFL, 0);
这同样可以在带O_NDELAY项打开串行端口后使用。
关闭串行端口
要关闭串行端口,只要使用 close 系统调用:
close(fd);
关闭串行端口通常同时将DTR信号设置为低,这将使多数MODEM挂机。
第二章,设置串行端口
本章讨论如何通过POSIX termios接口,在C语言中设置端口。
POSIX终端接口
多数系统支持通过POSIX终端 (串行) 接口来改变,例如波特率,字符尺寸,等参数。你需要做的第一件事情是引入文件 <termios.h>;它定义了终端控制结构和POSIX控制函数。
两个最重要的POSIX函数函数是 tcgetattr(3) 和 tcsetattr(3)。这些获得和设定相关的终端特性, 你要提供一个termios 结构的指针包含所有可用的串行设置项:
成员 | 描述 |
---|---|
c_cflag | 控制项 |
c_lflag | 线路项 |
c_iflag | 输入项 |
c_oflag | 输出项 |
c_cc | 控制字符 |
c_ispeed | 输入波特(新接口) |
c_ospeed | 输出波特(新接口) |
控制项
c_cflag成员控制波特率、数据位、校验、停止位和硬件流控制。所有支持的设置都有常数对应。常数 | 描述 |
---|---|
CBAUD | 波特率掩码 |
B0 | 0 波特 (drop DTR) |
B50 | 50 波特 |
B75 | 75 波特 |
B110 | 110 波特 |
B134 | 134.5 波特 |
B150 | 150 波特 |
B200 | 200 波特 |
B300 | 300 波特 |
B600 | 600 波特 |
B1200 | 1200 波特 |
B1800 | 1800 波特 |
B2400 | 2400 波特 |
B4800 | 4800 波特 |
B9600 | 9600 波特 |
B19200 | 19200 波特 |
B38400 | 38400 波特 |
B57600 | 57,600 波特 |
B76800 | 76,800 波特 |
B115200 | 115,200 波特 |
EXTA | 外部速率时钟 |
EXTB | 外部速率时钟 |
CSIZE | 位数据位掩码 |
CS5 | 5位数据位 |
CS6 | 6位数据位 |
CS7 | 7位数据位 |
CS8 | 8位数据位 |
CSTOPB | 2位停止位(不指明是1位) |
CREAD | 接收有效 |
PARENB | 校验位有效 |
PARODD | 使用奇校验代替偶校验 |
HUPCL | 最后关闭后,挂起(降低 DTR) |
CLOCAL | 本地线 - 不改变端口的"拥有者" |
LOBLK | 阻塞方式工作控制输出 |
CNEW_RTSCTS CRTSCTS | 采用硬件流控制(在所有的平台上都不支持) |
c_cflag成员包含两个选项必须总是有效,CLOCAL 和 CREAD。这些将保证你的程序不会成为端口的所有者, 从而妨碍控制工作和挂起信号,并使串行接口驱动将读取进入的数据。
波特率常数 (CBAUD, B9600, 等等。)是用来老式接口,那些缺少 c_ispeed 和 c_ospeed 成员的。参考下一章关于用于波特率设定的POSIX函数。
决不 直接初始化 c_cflag (或其它)成员;你应该总是用 AND, OR和NOT比特操作来设定或清除成员中的比特位。 不同的操作系统版本(甚至是补丁) 能也确实使用不同方式处理比特位,所以使用比特操作符,能够使你避免在使用一个新的串行设 备要用的比特位时遭到残败。
设置波特率
波特率存储于不同的位置依赖于具体系统。旧版本接口存储波特率在 c_cflag成员中,使用一个表4中的波特率常数, 而新的实现提供了c_ispeed和 c_ospeed 成员来包含波特率数值。
cfsetospeed(3) 和 cfsetispeed(3) 函数用于提供波特率设置到 termios 结构中,而不论其下的操作系统系统接口如何。
典型地你使用 列表 2 来设置波特率。
struct termios options; /* * Get the current options for the port... */ tcgetattr(fd, &options); /* * Set the 波特 rates to 19200... */ cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); /* * Enable the receiver and set local mode... */ options.c_cflag |= (CLOCAL | CREAD); /* * Set the new options for the port... */ tcsetattr(fd, TCSANOW, &options);
tcgetattr(3) 函数用当前的串行端口设置来填充你的termios结构。在我们设置了波特率、本地模式和串行数据接收, 我们使用tcsetattr(3)选定新的设置。TCSANOW常数表明所有的改变立即生效而不等待发送或接受的数据结束。还 有其它的参数常数用来等待输出和输入结束或刷新输入输出缓冲。
多数系统不支持端口有不同的输入与输出速率,所以确定设置为相同的值以获得最大的可移植性。
常数 | 描述 |
---|---|
TCSANOW | 立即改变,不等待数据结束 |
TCSADRAIN | 等待直到所有的都传完 |
TCSAFLUSH | 刷新输入输出缓冲,然后改变 |
设置字符尺寸
不同于波特率,没有简便的函数用于设定字符尺寸。取而代之的是你需要做一点比特掩码的操作来实现。字符的大小是以位方 式设定:
options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag |= CS8;= ~PARENB options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;
- 偶校验 (7E1):
options.c_cflag |= PARENB options.c_cflag &= ~PARODD options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS7;
- 奇校验 (7O1):
options.c_cflag |= PARENB options.c_cflag |= PARODD options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS7;= ~PARENB options.c_cflag &= ~CSTOPB options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;
设置硬件流控制
某些版本的UNIX支持硬件流控制,采用的是CTS (Clear To Send) 和RTS (Request To Send) 信号线。如果CNEW_RTSCTS 或 CRTSCTS 常数在你的系统上有定义,硬件流控制可能得到支持。以下用于选择硬件流控制:
options.c_cflag |= CNEW_RTSCTS; /* Also called CRTSCTS */
类似的,关闭硬件流控制:
options.c_cflag &= ~CNEW_RTSCTS;
本地项
本地模式成员 c_lflag 控制输入字符如何被串行驱动使用。一般你设置 c_lflag 成员为 canonical 或 raw 输入方式。
表 6 - c_lflag成员常数 常数 描述 ISIG 使SIGINTR, SIGSUSP, SIGDSUSP, SIGQUIT等信号作用 ICANON 设定规范canonical(或行式raw) XCASE Map uppercase /lowercase (废除) ECHO 回显输入字符 ECHOE 回显擦除字符 BS-SP-BS ECHOK 在删除字符后,回显 NL ECHONL 回显 NL NOFLSH 不在中断或退出字符后刷新输入缓冲 IEXTEN 扩展函数作用
ECHOCTL 以^char方式回显控制字符和以~?方式显示删除字符 ECHOPRT 回显提示有删除字符 ECHOKE BS-SP-BS整行,在有行删除时 FLUSHO 刷新输出 PENDIN 在下次读或输入时,将未决字符重打 TOSTOP 传送SIGTTOU信号作为背景 选择规范方式输入
规范方式输入是行式操作的。输入字符存放于一用户可编辑的缓冲中,直到接受到CR (回车)或 LF (进行)。
当选择这个模式时,你通常选择ICANON, ECHO, and ECHOE options:
options.c_lflag |= (ICANON | ECHO | ECHOE);
选择行方式输入
行式输入是不经处理的。输入字符在接受到后就直接传递,保持原样不处理。一般当你用行方式输入时,你需要去除 ICANON, ECHO, ECHOE, and ISIG 项:
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
关于回显的说明
决不 使用输入回显 (ECHO, ECHOE) ,当传送指令到一MODEM或其它计算机时,因为如果对方也回显字符的话,你就造成了在两个串口间反馈死循环!
输入项
输入模式成员 c_iflag 控制任何在端口接收字符的输入处理。类似 c_cflag 域,最终存储于 c_iflag 比特位符OR操作于期望项。
表 7 - c_iflag成员常数 常数 描述 INPCK 校验有效 IGNPAR 忽略校验错误 PARMRK 标记校验错误 ISTRIP 剥离校验位 IXON 软件流控制作用 (输出) IXOFF 软件流控制作用 (输入) IXANY 允许任何字符再次启动流 IGNBRK 忽略任何中断条件 BRKINT 传送SIGINT,当检测到中断 INLCR 映射NL到CR IGNCR 忽略CR ICRNL 映射CR到NL IUCLC 映射大写到小写 IMAXBEL 在输入线上回显BEL过长 设置输入校验项
当你在c_cflag成员中选择了校验作用(PARENB),你就应该使输入校验检查作用。输入校验检查的相关常数是INPCK, IGNPAR, PARMRK , 和 ISTRIP。一般你将选择 INPCK 和 ISTRIP 来检查和剥离校验位:
options.c_iflag |= (INPCK | ISTRIP);
IGNPAR 是个稍微有点危险的选项,告诉串行驱动忽略校验错误和传递输入数据,只当没有错误发生。在测试通讯链路质 量时有用,但一般没有实际使用的理由。
PARMRK 使用特殊字符将输入流中校验错误标记'marked'。如果 IGNPAR 作用,在每个有校验错误的字符前插入一个NUL字符 (000 八进制)。 除此之外,伴随错误字符发送DEL (177 八进制) 和 NUL 字符。
设置软件流控制
软件流控制通过设置 IXON, IXOFF 和 IXANY 常数:
options.c_iflag |= (IXON | IXOFF | IXANY);
取消软件流控制,只要简单地屏蔽那些数据位:
options.c_iflag &= ~(IXON | IXOFF | IXANY);
XON (开始传送数据) XOFF (停止数据传送) 字符的定义在 c_cc 数组中定义,描述如下。
输出项
c_oflag 成员包含输出过滤项。类似输入模式,你能选择处理或行式数据输出。
表 8 - c_oflag成员常数 常数 描述 OPOST 输出后处理 (不设置 = 行式输出) OLCUC 映射小写到大写 ONLCR 映射NL到CR-NL OCRNL 映射CR到NL NOCR 没有CR输出在列0 ONLRET NL实现CR功能 OFILL 对于延时用填充字符 OFDEL 填充字符DEL NLDLY 在行之间,需要掩蔽延时 NL0 NL没有延时 NL1 在换行后,新的输出前延时100ms CRDLY 回车到左边,需要掩蔽的延时 CR0 CR没有延时 CR1 CR后的延时,依赖于当前的列位置 CR2 CR后延时100ms CR3 CR后延时150ms TABDLY TAB后需要延时 TAB0 TAB后没有延时 TAB1 TAB后的延时根据当前的列位置 TAB2 TAB后延时100ms TAB3 TAB扩展为空格 BSDLY BS后需要延时掩蔽 BS0 BS后无延时 BS1 BS后延时50ms VTDLY VT后需要延时掩蔽 VT0 VT后无延时 VT1 VT后延时2秒 FFDLY FF后需要延时掩蔽 FF0 FF后无延时 FF1 FF后延时2秒 选择输出处理
输出处理是通过选择c_oflag成员中的OPOST :
options.c_oflag |= OPOST;
在众多不同的项目中,你可能只会用到ONLCR 项,该项映射换行为 CR-LF 对。余下的输出项主要都是出于历史原因,要追溯到打印机和终端还不能和串行数据流保持一致的时候!
选择行式输出
行式输出是通过重置c_oflag成员中的OPOST 项来实现的。
options.c_oflag &= ~OPOST;
当OPOST 设为不可用十,所有其它在c_oflag中的比特项都被忽略。
控制字符
c_cc 字符数组包含了控制字符和超时参数。数组的每个元素都有常数定义。
表 9 - c_cc成员中的控制字符 常数 描述 Key VINTR 中断 CTRL-C VQUIT 退出 CTRL-Z VERASE 擦除 空格(BS) VKILL 删行 CTRL-U VEOF 文件结尾 CTRL-D VEOL 行结尾 回车(CR) VEOL2 第二行结尾 进行(LF) VMIN 读取的最小字符数 - VTIME 等待时间(数十秒) - 设置软件流控制字符
c_cc数组的VSTART 和 VSTOP 元素包含用于软件流控制的字符。通常它们设定为DC1 (021 八进制) 和 DC3 (023 八进制),代表ASCII 标准的XON和XOFF字符。
设置读取超时
UNIX串行接口驱动提供确定的字符和包超时设定。c_cc 数组的两个元素用于该目的:VMIN 和 VTIME。 对于通过open或 fcntl的文件,在规范模式下canonical或当NDELAY项被设置,忽略超时设置。
VMIN 指明了最小的读取字符。如果它被设置为0,VTIME的值用于指明等待读取每个字符的时间。注意这不是意味着 read 调用读取N个字节需要等待N个字符进入。而是,超时将仅对第一个字符作用,并且read 调用将立即返回字符的个数 (最大为你要求的数目)。
如果 VMIN 非0,VTIME 指明了等待第一个字符到来的时间。如果在指定时间内读到一个字符,任何读操作将阻塞 (等待)直到所有VMIN 规定的字符数读到。那就是说,一旦第一个字符读到,串行接口驱动期望接收一整个包的字符 (VMIN 规定字符数)。如果在规定时间内没有字符被读取,read调用返回0。该方法允许你告诉串行驱动,你准确需要 N 个字节,以及 read 调用将只返回0或N字节。然而,超时只对第一个字符作用,所以如果由于某些原因驱动丢失了N个字 节包中的某个字符,read 调用将永远阻塞等待字符输入。
VTIME 指明等待输入的时间是以十分之一秒为单位。如果VTIME 设置为0 (缺省),读操作将不确定地阻塞(等待) ,直到用open or fcntl在端口上设置NDELAY 项。
第三章,MODEM通讯
本章包括了拨号调制/解调器(MODEM)的通讯基础知识。供MODEM使用的例子采用的是事实上的标准AT指令。
什么是MODEM?
MODEM是调制串行数据为频率信号,从而可以在模拟数据线路上传输,例如电话线或TV电缆接线。一个标准的电话MODEM转换串行数据 为语音,从而能够在电话线上传送,由于速度和复杂的转换机制,这些语音听起来象高声尖叫。
今天的电话MODEM能够在电话线上以每秒53,000比特的速率传输数据,或者说是53kbps。此外,多数MODEM使用数据压缩技术,从而可 将某些类型的比特速率提高到100kbps以上。
与MODEM通讯
和MODEM通讯的第一步是打开端口并设置为行方式输入,就象列表 3中所示。
int fd; struct termios options; /* open the port */ fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); fcntl(fd, F_SETFL, 0); /* get the current options */ tcgetattr(fd, &options); /* set raw input, 1 second 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] = 10; /* set the options */ tcsetattr(fd, TCSANOW, &options);
下一步是建立与MODEM的通讯。最好的办法是发送"AT"指令到MODEM。这还允许智能MODEM检测你使用的波特率。 当MODEM正确连接和加电,它将返回"OK"。
int /* O - 0 = MODEM ok, -1 = MODEM bad */ init_modem(int fd) /* I - Serial port file */ { char buffer[255]; /* Input buffer */ char *bufptr; /* Current char in buffer */ int nbytes; /* Number of bytes read */ int tries; /* Number of tries so far */ for (tries = 0; tries < 3; tries ++) { /* send 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 - 1)) > 0) { bufptr += nbytes; if (bufptr[-1] == '/n' || bufptr[-1] == '/r') break; } /* nul terminate the string and see if we got an OK response */ *bufptr = '/0'; if (strncmp(buffer, "OK", 2) == 0) return (0); } return (-1); }
标准MODEM指令
多数MODEM支持"AT"指令,这么称呼是因为每个指令都以"AT"字符开头。每个指令都以"AT"字符开头,跟以特殊指令和回车结尾(CR, 015 octal)。处理指令之后,MODEM将根据指令返回若干文本信息之一。
ATD - Dial A Number拨一个号码
ATD指令用户拨一个指定号码。除数字外,你还能添加少量内容,包括指明是语音("T")或脉冲("P")拨号,等待一秒 (",")和等待拨号音("W"):
ATDT 555-1212 ATDT 18008008008W1234,1,1234 ATD T555-1212WP1234
MODEM将返回以下信息之一:
NO DIALTONE BUSY NO CARRIER CONNECT CONNECT baud
ATH - Hang Up挂起
ATH指令导致MODEM挂起。因为MODEM是处于"命令"模式,你通常是不需要在普通通话中这么做。
DTR信号下降,将导致多数MODEM挂起;你可以通过将波特率设置为0至少一秒来实现。降低DTR信号同时也将MODEM返回命令模式。
在挂起成功后,MODEM将返回"NO CARRIER"。如果MODEM依然连接,将传回"CONNECT"或"CONNECT BAUD"。
ATZ - Reset MODEM 重置MODEM
ATZ指令重置MODEM。MODEM将返回字符"OK"。MODEM常见通讯问题
首先和最为重要的,不要忘记关闭输入回显。 输入回显将导致MODEM和计算机间形成反馈回路。
其次,在传输指令到MODEM时,必须以回车(CR)结尾,而不是新行(NL)。C对于CR的字符常数是"/r"。
最后,当操作MODEM时,请确认你使用的波特率是MODEM所支持的。尽管许多MODEM能够自动检测波特率,一些限制 (通常在老式MODEM上是19.2kbps)你必须注意。
第四章,高级串行编程
本章包括了高级串行编程技术,使用 ioctl(2) 和 select(2) 系统调用。
串行端口 IOCTLs
在第二章,串行端口设置中,我们使用 tcgetattr 和 tcsetattr 函数来设置串行端口。在UNIX下这些函数使用ioctl(2) 系统呼叫来实现其功能。
ioctl 系统调用使用三个参数:
int ioctl(int fd, int request, ...);
fd 参数指明串行端口文件描述符。 request 参数是一个常数定义于<termios.h>
头文件中,通常是列在表 10 中的某个常数。
Request | 描述 | POSIX Function |
---|---|---|
TCGETS | 获得串行端口设置。 | tcgetattr |
TCSETS | 立即设置串行端口。 | tcsetattr(fd, TCSANOW, &options) |
TCSETSF | 刷新输入输出缓冲后,设置串行端口。 | tcsetattr(fd, TCSAFLUSH, &options) |
TCSETSW | 允许输入输出缓冲排空后,设置串行端口。 | tcsetattr(fd, TCSADRAIN, &options) |
TCSBRK | 一个给定时间的中断 | tcsendbreak, tcdrain |
TCXONC | 软件流控制 | tcflow |
TCFLSH | 刷新输入输出缓冲 | tcflush |
TIOCMGET | 返回"MODEM"状态位。 | None |
TIOCMSET | 设定"MODEM"状态位。 | None |
FIONREAD | 返回输入缓冲中的比特数目 | None |
获得控制信号
TIOCMGET
ioctl 获得当前"MODEM"状态位,包含所有RS-232信号线,除了RXD和TXD, 列在表 11。
要获得状态位,调用 ioctl 带一个整数指针保存数据位,就象列表5 .
#include <unistd.h> #include <termios.h> int fd; int status; ioctl(fd, TIOCMGET, &status);
常数 | 描述 |
---|---|
TIOCM_LE | DSR (data set ready/line enable) |
TIOCM_DTR | DTR (data terminal ready) |
TIOCM_RTS | RTS (request 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) |
设定控制信号
TIOCMSET
ioctl 设置"MODEM"状态,定义如上。要降低DTR信号,你可以使用列表 6中的代码。
列表 6 - 使用TIOCMSET ioctl 降低DTR信号。
#include <unistd.h> #include <termios.h> int fd; int status; ioctl(fd, TIOCMGET, &status); status &= ~TIOCM_DTR; ioctl(fd, TIOCMSET, &status);
能够设定的数位依赖于操作系统,驱动和使用模式。查询你的操作系统文档以获得信息。
获得存在的比特字节个数
FIONREAD
ioctl 获得串行端口输入缓冲的字节个数。你传递TIOCMGET的同时用一个整数指针获得字节个数,例如
列表 7.
#include <unistd.h> #include <termios.h> int fd; int bytes; ioctl(fd, FIONREAD, &bytes);
这在用串行端口获得数据时很有用,使你的程序能够在尝试读取前确定字节个数。
从串行端口选择输入
虽然简单应用程序能够获得或等待串行端口的数据,多数应用程序并不简单并需要从多个来源获得输入。
UNIX通过select(2) 系统调用提供这一能力。系统调用允许你的程序检查输入,输出,或在一或多个文件描述符上的错误条件。 文件描述符能够指定到串行端口,普通文件,其它设备,管道或端口。你能检查获得的未完输入,等待输入结束,或者在指定时间后超时, 使用select系统呼叫非常灵活。
多数GUI工具提供了一个界面访问select;我们将在本章稍后讨论X Intrinsics ("Xt")库。
SELECT系统呼叫
select 系统呼叫能够接受5个参数:
int select(int max_fd, fd_set *input, fd_set *output, fd_set *error, struct timeval *timeout);
max_fd 参数指定了最高数字的文件描述符,在input, output, 和 error 集合。input, output, 和error 参数指明了用于未处理的文件描述符设置的输入,输出或错误条件;指定 NULL
来禁止检测相关条件。这些设置用以下三个宏初始化:
FD_ZERO(fd_set); FD_SET(fd, fd_set); FD_CLR(fd, fd_set);
FD_ZERO宏完全清除设定。FD_SET 和 FD_CLR 宏从设置中添加和移除相关的文件描述符。
超时 timeout 参数指明了超时设置由秒(timeout.tv_sec)和毫秒(timeout.tv_usec )组成。从一或多个文件描述符来源获得数据,设置秒和毫秒为零。无限等待,指定NULL
到超时指针。
select 系统调用返回未处理的文件描述符的个数,或者-1代表一个错误。
使用SELECT系统调用
假设我们从一个串行端口和一个套接字获得数据。我们从每个文件描述符检查输入,但同时想在10秒内没有输入时提醒用户。要实现这, 我们需要使用select系统调用,如列表 8.
#include <unistd.h> #include <sys/types.h> #include <sys/time.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 > /* Initialize the timeout structure */ timeout.tv_sec = 10; timeout.tv_usec = 0; /* Do the select */ n = select(max_fd, &input, NULL, NULL, &timeout); /* See if there was an error */ if (n < 0) perror("select failed"); else if (n == 0) puts("TIMEOUT"); else { /* We have input */ if (FD_ISSET(fd, input)) process_fd(); if (FD_ISSET(socket, input)) process_socket(); }
你注意到我们首先检查select 系统调用的返回值。0和-1值导致警告和错误信息。大于0的值表明有一或多个未处理的值。
要确定哪个文件描述符有没处理的输入,我们使用FD_ISSET 宏来测试每个文件描述符的输入设置。如果文件描述符设定了,且设定的条件出现(这里就是有输入没处理),我们就需要做点什么。
使用SELECT配合X Intrinsics库
X Intrinsics库提供了一个 select 系统调用的接口,通过 XtAppAddInput(3x) 和 XtAppRemoveInput(3x) 函数:
int XtAppAddInput(XtAppContext context, int fd, int mask, XtInputProc proc, XtPointer data); void XtAppRemoveInput(XtAppContext context, int input);
select 系统调用是内部使用,用于实现来自X server的超时,工作过程和输入检查。这些函数能够与任何基于Xt的工具一同使用,包括Xaw, Lesstif, and Motif。
XtAppAddInput的proc 参数指明了当在文件描述符上选定的条件出现时(例如,有输入),调用的函数。类似前面的例子,你可以用 process_fd 或 process_socket 函数。
因为Xt限制了你访问 select 系统调用,你需要用其它方法实现超时功能,可能的方法有通过XtAppAddTimeout(3x)。
Appendix A, Pinouts
This appendix provides pinout information for many of the common 串行 端口s you will find.
RS-232 Pinouts
RS-232 comes in three flavors (A, B, C) and uses a 25-pin D-Sub connector:
Figure 2 - RS-232 Connector
Pin | 描述 | Pin | 描述 |
---|---|---|---|
1 | Earth Ground | 14 | Secondary TXD |
2 | TXD - Transmitted Data | 15 | Transmit Clock |
3 | RXD - Received Data | 16 | Secondary RXD |
4 | RTS - Request To Send | 17 | Receiver Clock |
5 | CTS - Clear To Send | 18 | 未定义 |
6 | DSR - Data Set Ready | 19 | Secondary RTS |
7 | GND - Logic Ground | 20 | DTR - Data Terminal Ready |
8 | DCD - Data Carrier Detect | 21 | Signal Quality Detect |
9 | Reserved | 22 | Ring Detect |
10 | Reserved | 23 | Data Rate Select |
11 | 未定义 | 24 | Transmit Clock |
12 | Secondary DCD | 25 | 未定义 |
13 | Secondary CTS |
RS-422 Pinouts
RS-422 also uses a 25-pin D-Sub connector, but with differential signals:
Figure 3 - RS-422 Connector
Pin | 描述 | Pin | 描述 |
---|---|---|---|
1 | Earth Ground | 14 | TXD+ |
2 | TXD- - Transmitted Data | 15 | Transmit Clock- |
3 | RXD- - Received Data | 16 | RXD+ |
4 | RTS- - Request To Send | 17 | Receiver Clock- |
5 | CTS- - Clear To Send | 18 | 未定义 |
6 | DSR - Data Set Ready | 19 | RTS+ |
7 | GND - Logic Ground | 20 | DTR- - Data Terminal Ready |
8 | DCD- - Data Carrier Detect | 21 | Signal Quality Detect |
9 | Reserved | 22 | 未定义 |
10 | Reserved | 23 | DTR+ |
11 | 未定义 | 24 | Transmit Clock+ |
12 | DCD+ | 25 | Receiver Clock+ |
13 | CTS+ |
RS-574 (IBM PC/AT) Pinouts
The RS-574 interface is used exclusively by PC manufacturers and uses a 9-pin male D-Sub connector:
Figure 4 - RS-574 Connector
Pin | 描述 | Pin | 描述 |
---|---|---|---|
1 | DCD - Data Carrier Detect | 6 | Data Set Ready |
2 | RXD - Received Data | 7 | RTS - Request To Send |
3 | TXD - Transmitted Data | 8 | CTS - Clear To Send |
4 | DTR - Data Terminal Ready | 9 | Ring Detect |
5 | GND - Logic Ground |
SGI Pinouts
Older SGI equipment uses a 9-pin female D-Sub connector. Unlike RS-574, the SGI pinouts nearly match those of RS-232:
Figure 5 - SGI 9-Pin Connector
Pin | 描述 | Pin | 描述 |
---|---|---|---|
1 | Earth Ground | 6 | DSR - Data Set Ready |
2 | TXD - Transmitted Data | 7 | GND - Logic Ground |
3 | RXD - Received Data | 8 | DCD - Data Carrier Detect |
4 | RTS - Request To Send | 9 | DTR - Data Terminal Ready |
5 | CTS - Clear To Send |
The SGI Indigo, Indigo2, and Indy workstations use the Apple 8-pin MiniDIN connector for their 串行 端口s:
Figure 6 - SGI 8-Pin Connector
Pin | 描述 | Pin | 描述 |
---|---|---|---|
1 | DTR - Data Terminal Ready | 5 | RXD - Received Data |
2 | CTS - Clear To Send | 6 | RTS - Request To Send |
3 | TXD - Transmitted Data | 7 | DCD - Data Carrier Detect |
4 | GND - Logic Ground | 8 | GND - Logic Ground |
Appendix B, ASCII Control Codes
This chapter lists the ASCII control codes and their names.
Control Codes
The following 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 | 5 | 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 |
Name | Binary | Octal | Decimal | Hexadecimal |
CR | 00001101 | 015 | 13 | 0D |
SO | 00001110 | 016 | 14 | 0E |
SI | 00001111 | 017 | 15 | 0F |
DLE | 00010000 | 020 | 16 | 10 |
XON, DC1 | 00010001 | 021 | 17 | 11 |
DC2 | 00010010 | 022 | 18 | 12 |
XOFF, DC3 | 00010011 | 023 | 19 | 13 |
DC4 | 00010100 | 024 | 20 | 14 |
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 |
US | 00011111 | 037 | 31 | 1F |
Appendix C, GNU Free Documentation License
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of "copyleft", it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the Document or a 端口ion of it, either copied verbatim, or with modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is sui表 for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is sui表 for input to text formatters or for automatic translation to a variety of formats sui表 for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".
Examples of sui表 formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
- A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
- B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
- C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
- D. Preserve all the copyright notices of the Document.
- E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
- F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
- G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
- H. Include an unaltered copy of this License.
- I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
- J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
- K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
- L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
- M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
- N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
- O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
Appendix D, Change History
This appendix lists the changes made to the document with each revision.
Edition 5, Revision 3
The following changes were made for the 3rd revision:
- Now use the GNU Free Documentation License for the guide.
- Changed the examples to use the Linux 串行 端口 filenames.
- Put the infrastructure in place to allow for easier translations of the guide.
- The guide text is now fully justified.