很久以前,串行端口的名称很简单。除了某些多端口串行卡,它们被命名为 /dev/ttyS0, /dev/ttyS1 等。大约在 2000 年左右,出现了 USB 总线,其名称如 /dev/ttyUSB0 和 /dev/ttyACM1 (用于 USB 总线上的 ACM 调制解调器)。
由于 DOS 为旧 ISA 总线上的 4 个串行端口提供了支持:COM1-COM4, ttyS0-ttyS3,因此更新的 PCI 总线上的大多数串行端口都使用了更高的数字,例如 ttyS4 或 ttyS14 (在内核 2.6.13 之前)。但是,由于大多数 PC 仅配备一个或两个串行端口,ttyS0 和可能的 ttyS1 (用于第二个端口),因此 PCI 总线现在可以使用 ttyS2 (内核 2.6.15 及更高版本)。这一切使得在同一台 PC 上同时拥有 ISA 串行端口和 PCI 串行端口而没有名称冲突成为可能。0-1 (或 0-3) 保留给旧的 ISA 总线 (或更新的 LPC 总线),而 2-向上 (或 4-向上或 14-向上) 用于 PCI。虽然不一定必须如此,但通常是这样。主板上同时具有 PCI 和 ISA 插槽的板载串行端口很可能仍然是 ISA 端口。即使对于全 PCI 插槽的主板,串行端口通常也不是 PCI。相反,它们要么是 ISA,要么在内部 ISA 总线上,要么在 LPC 总线上,LPC 总线旨在用于低速传统 I/O 设备:串行/并行端口和软盘驱动器。
Linux 中的设备具有主设备号和次设备号。串行端口 ttySx (x=0,1,2, 等) 的主设备号为 4。您可以通过在 /dev 目录中键入 "ls -l ttyS*" 来查看这一点 (以及次设备号)。要查找各种设备的设备名称,请参阅内核文档中的 "devices" 文件。
以前每个串行端口都有一个 "cua" 名称,它的行为略有不同。例如,ttyS2 将对应于 cua2。它主要用于调制解调器。cua 的主设备号为 5,次设备号从 64 开始。您的 /dev 目录中可能仍然有 cua 设备,但它们现在已被弃用。有关详细信息,请参阅 Modem-HOWTO,章节:cua 设备已过时。
有关在设备目录中创建旧设备的信息,请参阅:Serial-HOWTO:“在 /dev 目录中创建设备”。
Dos/Windows 使用 COM 名称,而来自串行驱动程序的消息使用 ttyS00, ttyS01 等。较旧的串行驱动程序 (2001 年 ?) 仅使用 tty00, tty01 等。
下表显示了一些串行设备名称的示例。IO 地址是旧 ISA 总线的默认地址 (不适用于较新的 PCI 和 USB 总线)。
dos common IO USB-BUS ( ACM => acm modem )
name name major minor address || common name common name
COM1 /dev/ttyS0 4, 64; 3F8 || /dev/ttyUSB0 | /dev/ttyACM0
COM2 /dev/ttyS1 4, 65; 2F8 || /dev/ttyUSB1 | /dev/ttyACM1
COM3 /dev/ttyS2 4, 66; 3E8 || /dev/ttyUSB2 | /dev/ttyACM2
COM4 /dev/ttyS3 4, 67; 2E8 || /dev/ttyUSB3 | /dev/ttyACM3
- /dev/ttyS4 4, 68; various
有关更多信息,请参阅内核文档目录中的 usb 子目录,文件包括:usb-serial, acm 等。
在某些安装中,将创建两个额外的设备,/dev/modem
用于您的调制解调器,/dev/mouse
用于鼠标。这两个都是指向 /dev
中相应设备的符号链接。
历史记录:以前 (在 1990 年代) 不鼓励使用 /dev/modem
(作为指向调制解调器串行端口的链接),因为锁文件可能无法意识到它实际上是 /dev/ttyS2
。较新的锁文件系统不会陷入此陷阱,因此现在可以使用此类链接。
内核 2.4 引入了现在已过时的可选 "设备文件系统" (devfs),它为所有事物提供了一整套新的名称。但在 2003-4 年,有人声称 devfs 存在无法解决的问题,并且从内核 2.6.12 开始,它被 "udev" 取代 (内核 2.6.12 之前的版本也可以使用 udev,但存在一些问题)。虽然 udev 没有提供 devfs 的所有功能,但它确实处理热插拔。此外,运行 Linux 并非必须使用 udev,因此有些人不使用它。但许多发行版默认安装它。
Devfs 是一个好主意,并且据称比 udev 更有效率。但不幸的是,devfs 的作者没有长期维护它,据称它变得维护不善。因此,无论好坏,我们现在都使用 udev 而不是 devfs,尽管关于 devfs 与 udev 的争论仍在继续。有关 devfs 的详细描述,请参阅:http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html 另请参阅内核文档树:filesystems/devfs。
devfs 的设备名称可以在 udev 中使用,但通常不使用,并且可能不容易激活。以下是串行设备的 devfs 名称:ttyS1 变为 tts/1,ttyUSB1 变为 /usb/tts/1,ttyACM1 变为 /usb/acm/1。请注意,上面的数字 1 只是一个示例。它可以替换为 0、2、3、4 等。udev 名称的更多示例:ttyS2 变为 tts/2 (串行端口),tty3 变为 vc/3 (虚拟控制台),ptyp1 变为 pty/m1 (PTY 主设备),ttyp2 变为 pty/s2 (PTY 从设备)。"tts" 看起来像一个目录,其中包含设备 "文件":0、1、2 等。所有这些新名称都应该仍然在 /dev 目录中,尽管可以选择将它们放在其他位置。
对于 devfs,/dev 目录中的设备名称由相应的驱动程序自动创建。因此,如果串行支持来自模块并且该模块尚未加载,则 /dev 目录中将没有任何串行设备。这可能会令人困惑:您物理上拥有串行端口,但在 /dev 目录中看不到它们。但是,如果将设备名称告知通信程序并且串行模块未加载,则内核应该尝试为其查找驱动程序并在 /dev 目录中为其创建名称。
如果找到驱动程序,这可以正常工作。但是,假设没有找到它的驱动程序。例如,如果您尝试使用 "setserial" 配置驱动程序未能检测到的端口,它会声称没有这样的端口。在这种情况下,如何创建 devfs 端口?
例如,对于多端口设备,/dev/ttyF9 变为 /dev/ttf/9,或者在更高版本中变为 /dev/tts/F9。将 F (或 f) 替换为您多端口板为此目的使用的任何字母。多端口驱动程序应该创建一个类似于上述的 devfs 名称,并将其放入 /dev 目录中。
每个 ttyS 设备都有一个对应的 cua 设备。但是 cua 设备已被弃用,因此最好使用 ttyS (除非需要 cua)。cua 和 ttyS 之间存在差异,但是精明的程序员可以使 ttyS 端口的行为与 cua 端口完全相同,因此不再真正需要 cua。除非某些旧程序可能需要使用 cua。
有什么区别?cua 和 ttyS 之间的主要区别与 C 程序中当普通的 "open" 命令尝试打开端口时发生的事情有关。如果 cua 端口已设置为检查调制解调器控制信号,则即使 CD 调制解调器控制信号指示不应该打开端口,也可以打开该端口。通过巧妙的编程 (通过在程序中添加额外的行),也可以强制 ttyS 端口也以这种方式运行。但是,即使调制解调器未能升高 CD (因为没有人呼入并且没有载波),cua 端口也可以更容易地编程为打开以拨出调制解调器。这就是为什么 cua 曾经用于拨出,而 ttyS 用于拨入的原因。
从 Linux 内核 2.2 开始,当使用 cua 时,内核日志中会放置一个警告消息。这是一个 cua 已失效并且应尽可能避免使用的预兆。