第15章 串口通信
15.1 概要
UNIX一直都是支持串口通信的。事实上,早期的UNIX系统就是利用串行线来输入和输出数据的。那时通常的“terminal”包括了一个每秒10个字符的串行打印机和键盘,现在这些已经发生了很大的变化。这章将介绍一些利用FreeBSD进行串行通信的方法。
读完这章,你将了解到:
如何通过终端连接到你的FreeBSD系统。
如何使用modem拨号到远程主机。
如何允许远程用户通过modem登陆到你的系统。
如何从串行控制台引导你的系统。
阅读这章之前,你应当了解:
如何配置和安装一个新的内核。(第9章)
理解UNIX的权限和进程。(第3章)
通过你喜欢使用的串行设备(modem或多端口卡)访问技术参考手册。
15.2 介绍
15.2.1 术语
bit/s
每秒位——数据的传输速度
DTE
数据终端设备——如你的计算机
DCE
数据通信设备——如你的modem
RS-232
用于硬件串行通信的EIA标准
当讨论通讯数据速度的时候,这节不会使用术语“baud”。Baud指电气标准传输率,它已经使用了很长时间,而“bit/s”(bits
per second)才是正确使用的术语(至少它不会打扰那些爱争吵的家伙)。
15.2.2线缆和端口
要连接一个modem或终端到你的FreeBSD系统,你需要有一个串行端口,和连接到你串行设备的适当的线缆。如果你比较熟悉硬件和它要求的线缆,你可以跳过这节。
线缆
有好几种不同的串行线缆。两个最普通的类型是null-modem线缆和标准RS-232线缆。你硬件的规格说明会有详细描述。
Null-modem 线缆
一根null-modem线缆会直接通过像“signal ground”这样的信号,而转换其他的信号。
如果你想自己选择线缆,你可以做一个使用null-modem的线缆。这个线缆在一个DB-25连接器上会显示RS-232C信号名和pin号码。
|
Signal |
Pin
# |
|
Pin
# |
Signal |
|
TxD |
2 |
连接到 |
3 |
RxD |
|
RxD |
3 |
连接到 |
2 |
TxD |
|
DTR |
20 |
连接到 |
6 |
DSR |
|
DSR |
6 |
连接到 |
20 |
DTR |
|
SG |
7 |
连接到 |
7 |
SG |
|
DCD |
8 |
连接到 |
4 |
RTS |
|
RTS |
4 |
|
5 |
CTS |
|
CTS |
5 |
连接到 |
8 |
DCD |
标准RS-232C线缆
一个标准的串行线缆会直接通过所有的RS-232C信号。这是连接一个modem到你的FreeBSD系统的线缆类型,线缆的类型需要针对一些终端。
端口
串行端口是FreeBSD主机与终端传输数据的设备。这节描述了端口的种类和他们在FreeBSD上是如何编址的。
端口的种类
有好几种端口存在。你在购买和做线缆之前,你需要确定它是否适合你机器的终端。
绝大多数的终端有DB25端口。个人计算机包括运行FreeBSD的PC机,有DB25或DB9端口。如果你的计算机有一个多端口的串行卡,你可以使用RJ-12 或RJ-45端口。请仔细看看硬件的说明。
端口名称
在FreeBSD中,你可以通过/dev目录中的一个记录来访问每个串行端口。有两种不同的记录:
呼入端口被命名为/dev/ttydN,这儿N是端口号,从零开始。通常,你使用呼入端口作为终端。呼入端口要求数据线使用载波检测(DCD)信号来工作。
呼出端口被命名为/dev/cuaaN。你通常不使用呼出端口作为终端,只使用modem。如果串行线或终端不支持载波检测数据传输,你可以使用呼出端口。
如果你已经连接一个终端到第一个串行端口(在MSDOS上是COM1),那你可以使用/dev/ttyd0来作为终端。如果它是在第二个串行端口(COM2),那就是/dev/ttyd1,等等。
15.2.3内核配置
FreeBSD默认支持4个串行端口。在MS-DOS下,这些是COM1:,COM2:,COM3:和COM4:。FreeBSD当前支持“dumb”多端口串行接口卡,如BocaBoard 1008和2016,与许多Digiboard 和Stallion
Technologies制造的智能多接口卡一样好。然而,默认的内核只会寻找标准的COM端口。
要看看你的内核是否支持你的串口,只要在内核启动时查看一下启动信息,或使用/sbin/dmesg命令重新检测内核启动信息。特别的,寻找以sio字符启动的信息。
提示:要看看带有sio字符的信息,可以使用下面的命令:
# /sbin/dmesg | grep 'sio'
例如,在一个带有4个串口的系统上,这些是串口特定的内核启动信息:
sio0 at 0x3f8-0x3ff irq 4
on isa
sio0: type 16550A
sio1 at 0x2f8-0x2ff irq 3
on isa
sio1: type 16550A
sio2 at 0x3e8-0x3ef irq 5
on isa
sio2: type 16550A
sio3 at 0x2e8-0x2ef irq 9
on isa
sio3: type 16550A
如果你的内核没有认出你的所有串口,你需要为你的系统定制一个内核。更多有关配置内核的细节,可以看看第9章。
在你的内核配置文件中相关的设备行是这样的:
device sio0 at isa? port “IO_COM1” tty
irq 4 vector siointr
device sio1 at isa? port “IO_COM2” tty
irq 3 vector siointr
device sio2 at isa? port “IO_COM3” tty
irq 5 vector siointr
device sio3 at isa? port “IO_COM4” tty
irq 9 vector siointr
你可以注释掉或完全删除你没有的设备。请看看sio的有关如何为你的多端口主板写入配置信息的联机手册。如果你使用了一个不同版本的FreeBSD的配置文件,请小心点,因为设备的标记在两个版本之间已经改变了。
注意:这里端口IO_COM1代替了0x3f8,端口IO_COM2代替了0x2f8,端口IO_COM3代替了0x3e8,端口IO_COM4代替了0x2e8,这些都是各自端口相应的端口地址。中断4,3,5,9都是经常用的中断。也要注意有些正常的串行端口可能无法在一些ISA总线的PC上共享中断(多端口板卡有板载的电子设备,允许在板上所有16550A的设备共享一个或两个中断请求)。
15.2.4设备指定文件
内核中的绝大多数设备可以通过“device special files”来访问,它就在/dev目录下。Sio设备通过/dev/ttydN(拨入)和/dev/cuaaN(拨出)设备来访问。FreeBSD也提供了初始化的设备(/dev/ttyidN和/dev/cuai0N)和锁定的设备(/dev/ttyldN和/dev/cual0N)。初始化的设备在每次端口被打开时被用来初始化设备通信端口参数。例如使用CTS/RTS的流控制信号的crtscts。锁定设备被用来锁定端口的标记以阻止用户或程序改变某个参数。看看termios,sio, 和stty的联机手册了解更多信息。
编译设备指定文件
注意:FreeBSD5.0已把自动创建设备接点的devfs文件系统作为是必需的。如果你在运行启用devfs的FreeBSD版本,你就可以跳过这一节。
一个在/dev目录下的叫做MAKEDEV的shell脚本管理着设备指定文件。要使用MAKEDEV来建立拨号设备指定文件,可以使用COM1:(port
0),cd 进入/dev,然后执行命令MAKEDEV ttyd0。同样地,要建立拨号设备指定文件以使用COM2:(port 1),可以执行MAKEDEV ttyd1。
MAKEDEV不仅仅创建/dev/ttydN设备指定文件,也创建/dev/cuaaN,/dev/cuaiaN, /dev/cualaN,/dev/ttyldN,和/dev/ttyidN节点。
建立完新设备指定文件后,需要检查文件的权限来确定谁可以在这些文件上读写——你可能不想让普通的用户使用你的modem吧。在/dev/cua*文件上的默认权限应该是足够了:
crw-rw——- 1 uucp dialer 28, 129 Feb 15 14:38
/dev/cuaa1
crw-rw——- 1 uucp dialer 28, 161 Feb 15 14:38
/dev/cuaia1
crw-rw——- 1 uucp dialer 28, 193 Feb 15 14:38
/dev/cuala1
这些许可允许用户uucp和在组dialer上的用户使用呼出设备。
15.2.5串行端口配置
ttydN(或cuaaN)设备是你将要打开的应用程序的正常设备。当一个进程打开某个设备时,它将有一个终端I/O设置的默认配置。你可以在命令行看看这些设置:
# stty -a -f /dev/ttyd1
当你修改了这个设备的设置,这个设置会生效,除非设备被关闭。当它被重新打开时,它将回到默认设置。要修改默认设置,你可以打开和调整“initial state”设备的设置。例如,要为ttyd5打开CLOCAL模式,8位通信和默认的XON/XOFF流控制,键入:
# stty -f /dev/ttyid5
clocal cs8 ixon ixoff
串行设备的系统初始化是用/etc/rc.serial文件类控制的。这个文件会影响串行设备的默认设置。
要防止某个设置被一个应用程序所修改,需要调整“lock state”设备。例如,要锁定ttyd5的速度为57600
bit/s,键入:
# stty -f /dev/ttyld5 57600
现在,一个打开ttyd5和设法改变端口速度的应用程序将被固定在57600bit/s。很自然地,你需要确定初始状态,然后只用root帐户锁定状态设备的写入功能。
15.3 终端
当你在计算机控制台或是在一个连接的网络上时,终端提供了一个方便和低成本的访问FreeBSD系统的方法。这节描述了如何在FreeBSD上使用终端。
15.3.1终端的用法和类型
早期的UNIX系统没有控制台。人们通过将终端连接到计算机的串口来登陆和使用程序。它很像用一个modem和一些终端软件来拨号进入一个远程的系统只执行文本的工作。今天的PC已经可以使用高质量的图形了,但与今天的其他UNIX操作系统一样,建立一个登陆会话的能力仍然存在。通过使用一个终端连接到一个没有使用的串口,你就能登陆和运行任何文本程序或在X 视窗系统中运行一个xterm窗口程序。
对于商业用户,你可以配上任何终端连接到FreeBSD系统,然后把它们放在员工的桌面上。对于一个家庭用户,可以使用一台比较老的IBM PC或Macintosh运行一个终端连接到一台运行FreeBSD的高性能机器上。
对于FreeBSD,有三种终端:
Dumb终端
充当终端的PC
X 终端
下面一小节将描述每一种终端。
Dumb终端
Dumb终端需要专门的好几种硬件,让你通过串行线连接到计算机。它们被叫做“dumb”是因为它们只能够用来显示,发送和接收文本。你不能在它上面运行任何程序。
有好几百种dumb终端,包括Digital
Equipment Corporation的VT-100和Wyse的WY-75。只有几种可以在FreeBSD上工作。一些高端的终端可以显示图形,但只有某些软件包可以使用这些高级特性。
充当终端的PC
如果一个dumb终端有足够的能力来显示,发送和接收文本,那任何个人计算机都可以作为一个dumb终端。你所需要的只是适当的线缆和一些终端模拟软件。
这样一个配置被广泛运用于家庭。例如,如果你的妻子忙于在你的FreeBSD系统控制台上工作,你也可以从一台低档的个人计算机登陆到FreeBSD系统执行一些文本的工作。
X 终端
X终端是最复杂的终端系统。它们通常需要使用以太网来连接。他们能显示任何X应用程序。我们介绍X终端只是为了感兴趣。然而,这章不会涉及X终端的安装,配置或使用。
15.3.2配置
这节描述了你在一个终端上启用一个登陆会话,需要在FreeBSD系统上配置些什么。假设你已经配置好了内核来支持串行端口,你就可以连接了。
回想起第7章,init进程依赖于系统启动时所有的处理控制和初始化。通过init来执行的一些任务将先读取/etc/ttys文件,然后在可用的终端上启用一个getty进程。getty进程可用来阅读一个登陆名和启动login程序。
然而,要为你的FreeBSD系统配置终端,你需要以root来执行下面的步骤:
1. 如果它不在那儿,你需要为串行端口在/dev目录下添加一行记录到/etc/ttys。
2. 指定/usr/libexec/getty在端口上运行,然后从/etc/gettytab文件指定适当的getty类型。
3. 指定默认的终端类型。
4. 设置端口为on。
5. 确定端口是否为secure。
6. 迫使init重新读取/etc/ttys文件。
作为可选的步骤,你可以通过在/etc/gettytab中建立一个记录,在第2步创建一个定制的getty类型来使用。这章不会介绍如何做。你可以看看gettytab和getty的联机手册了解更多信息。
添加一个记录到/etc/ttys
/etc/ttys文件列出了你FreeBSD系统上允许登陆的所有端口。例如,第一个虚拟控制台ttyv0在这个文件中有一个记录。你可以使用这个记录登陆进控制台。这个文件也包含其他虚拟控制台的记录,串口,和伪ttys终端。对于一个硬连线的终端,只要列出串行端口的/dev记录而不需要/dev部分(例如,/dev/ttyv0可以被列为ttyv0)。
默认的FreeBSD安装包括一个支持最初四个串口ttyd0 到ttyd3的/etc/ttys文件。如果你从那些端口中某一个使用终端,你不需要添加另一个记录。
例15-1.添加终端记录到/etc/ttys
假设我们连接两个终端给系统:一个Wyse-50和一个老的运行Procomm终端软件模拟一个VT-100终端的286IBM PC。在/etc/ttys文件中的相应的记录是这样的:
ttyd1
“/usr/libexec/getty std.38400”
wy50
on
insecure
ttyd5 “/usr/libexec/getty
std.19200” vt100 on insecure
·
第一部分指定了终端指定文件的名称,它可以在/dev中找到。
![]()