下一页 上一页 目录

11. 你应该知道的有趣程序

关于 getty 的大部分信息已移至 Modem-HOWTO,而关于将 getty 与直接连接的终端一起使用的少量信息现在位于 Text-Terminal-HOWTO 中。

11.1 串行监控/诊断程序

一些 Linux 程序(和一个“文件”)将监控各种调制解调器控制线,并指示它们是正(1 或绿色)还是负(0 或红色)。

截至 1998 年 6 月,据我所知,Linux 中没有用于串行端口的诊断程序。

11.2 更改中断优先级

11.3 什么是 Setserial?

这部分内容在 3 个 HOWTO 中:Modem、Serial 和 Text-Terminal。根据它出现在哪个 HOWTO 中,存在一些细微的差异。

Setserial 在 linmodems、笔记本电脑上的问题

如果您有笔记本电脑 (PCMCIA),请在阅读 笔记本电脑:PCMCIA 之前不要使用 setserial

介绍

setserial 是一个程序,供用户与串行设备驱动程序通信。如果您只使用 PC 标配的一个或两个串行端口,通常永远不需要使用它。即使在其他情况下,大多数额外的串行端口也应该被现代内核自动检测到。除非您的旧 ISA 串行端口是通过物理硬件上的跳线设置的,或者您的内核(例如 2.2 或更旧版本)既不检测也不设置您的附加 PCI 串行端口,否则您才需要使用 setserial。

setserial 允许您(或 shell 脚本)与串行软件对话。但是还有另一个程序 tt/stty/,它也处理串行端口,用于设置端口速度等。

setserial 处理串行端口的较低级别配置,例如处理 IRQ(例如 5)、端口地址(例如 3f8)等。它的一个主要问题是它无法设置或配置串行端口硬件:它无法将 IRQ 或端口地址设置到硬件中。此外,当它看似报告硬件的配置时,有时是错误的,因为它实际上并没有探测硬件,除非您明确告诉它这样做。即使那样,它也不会进行现代类型的总线探测,并且某些硬件可能永远不会被它找到。尽管如此,它显示的内容在大多数情况下都是正确的,但是如果您在使串行端口工作时遇到问题,那么很有可能它是错误的。

在过去,当 IRQ 和端口地址通过串行卡上的跳线设置时,人们会使用 setserial 来告诉驱动程序这些跳线是如何设置的。如今,当即插即用方法检测到无跳线串行端口是如何设置的时,除非您遇到问题或使用旧硬件,否则实际上不再需要 setserial。此外,如果 setserial 使用的配置文件不正确,则会出现问题。在这种情况下,如果您使用 setserial 尝试找出端口是如何配置的,它可能只会重复配置文件中的不正确信息。

setserial 有时可以帮助找到串行端口。但只有当您知道端口地址并使用正确的选项时才有用。对于现代端口,通常有更好的方法通过即插即用方法来查找它们。

因此,名称 setserial 有点用词不当,因为它没有在硬件中设置 I/O 地址或 IRQ,它只是在驱动程序软件中“设置”它们。并且驱动程序天真地认为 setserial 告诉它什么,即使它与驱动程序使用即插即用方法找到的内容冲突。糟糕的是,它至少没有为这种冲突发出警告消息。由于设备驱动程序被认为是内核的一部分,因此在其他文档中经常使用“内核”一词,而没有提及任何“串行驱动程序”。

某些发行版(和版本)设置了一些东西,以便在启动时通过初始化 shell 脚本(在 /etc 目录树中)运行 setserial。但是此脚本使用的配置文件可能位于 /etc 树或 /var 树中。在某些情况下,如果您希望 setserial 在启动时运行,您可能需要采取一些操作。如果没有内置到内核或作为模块加载的串行支持,setserial 将无法工作。如果您(或脚本)尝试使用 setserial,则模块可能会自动加载。

虽然可以使 setserial 探测硬件 IO 端口地址以尝试确定 UART 类型和 IRQ,但这有严重的局限性。请参阅 探测。它无法在 PnP 或 PCI 串行端口的硬件中设置 IRQ 或端口地址(但串行驱动程序的即插即用功能可能会执行此操作)。它也不能直接读取存储在硬件配置寄存器中的 PnP 数据。但是由于设备驱动程序可以读取这些寄存器,并且 setserial 告诉您设备驱动程序的想法,因此它可能是正确的。或者它可能是在告诉您 setserial 之前(可能错误地)告诉驱动程序的内容。如果不进行其他一些检查,就无法确定。

串行驱动程序(对于 Linux 内核 2.4+)查找一些“标准”传统串行端口、ISA 总线上的 PnP 端口以及 PCI 总线上的所有受支持端口硬件。如果它正确找到您的端口,则无需使用 setserial。驱动程序不会探测使用卡上跳线设置的旧 ISA 串行端口的 IRQ,并且可能会弄错这些 IRQ。

除了 setserial 的 man 手册页之外,还要查看 /usr/doc/setserial...//usr/share/doc/setserial 中的信息。这应该告诉您如何处理 Linux 发行版的 setserial。虽然 setserial 在所有发行版中的行为都相同,但用于运行它的脚本、如何配置此类脚本(包括自动配置)以及脚本文件的名称和位置等都与发行版相关。

串行模块卸载

如果串行模块被卸载,则驱动程序将忘记先前由 setserial 所做的更改。但是,当驱动程序忘记它时,发行版提供的脚本可能会将其保存在某个文件中,以便在重新加载模块时可以恢复它。

1200 或更慢的慢速波特率

曾经有一个关于慢速串行打印机(尤其是 1980 年代的旧打印机)的问题。打印程序会在打印“结束”时关闭串行端口,远早于将大型串行缓冲区(在主内存中)中的所有字符发送到打印机。结果是打印作业被截断,没有打印最后一段或最后一页等。

但是较新的 lprng 打印程序(以及可能还有其他打印程序)会保持端口打开直到打印完成,因此“问题已解决”,即使您使用的是古老的打印机。Setserial 可以修改端口在关闭后保持运行的时间(以便输出主 RAM 缓冲区中仍然存在的任何字符)。这是通过 setserial man 手册页中的“closing_wait”选项完成的。对于过早关闭端口的“不良”软件,如果存在大量“流控制”等待,则在 1200 以上的速度下也可能需要它。

给出 setserial 命令

请记住,setserial 无法在硬件中设置任何 I/O 地址或 IRQ。这是通过即插即用软件(由驱动程序运行)或传统串行端口的跳线完成的。即使您通过 setserial 向驱动程序提供 I/O 地址或 IRQ,它也不会设置这些值,并假定它们已被设置。如果您给它错误的值,串行端口将无法正常工作(如果可以工作)。

对于传统端口,如果您知道 I/O 地址但不知道 IRQ,您可以命令 setserial 尝试确定 IRQ。

您只需键入 setserial 而不带任何参数即可看到可能的命令列表。这未能向您显示单字母选项,例如 -v(用于详细),您通常应该在进行故障排除时使用它。请注意,setserial 将 IO 地址称为“端口”。如果您键入

setserial -g /dev/ttyS*
您将看到一些关于设备驱动程序如何为您的端口配置的信息。在许多情况下,您会看到一些端口显示的信息,乍一看似乎是错误的 IRQ 和地址。但是,如果您还看到:“UART: unknown”,请忽略整行,因为该地址上不存在串行端口。

如果您将 -a 添加到选项 -g,您将看到更多信息,尽管很少有人需要处理(或理解)此附加信息,因为您看到的默认设置通常可以正常工作。在正常情况下,硬件的设置方式与“setserial”报告的方式相同。但是,如果您遇到问题,则很可能 setserial 弄错了。实际上,您可以运行“setserial”并分配一个纯粹虚构的 I/O 端口地址、任何 IRQ 以及您想要的任何 uart 类型。然后,下次您键入“setserial ...”时,它将显示您提供给驱动程序的这些伪造的值。它们也将被正式注册到内核中,如“scanport”命令(Debian)在屏幕顶部显示的那样。当然,如果您尝试使用这样的端口,串行端口驱动程序将无法正常工作(如果可以工作)。因此,当向 setserial 提供参数时,“一切皆有可能”。好吧,几乎是这样。如果您为一个端口分配一个已分配的基地址(例如 3e8),它可能不会接受它。但是如果您使用 3e9,它将接受它。不幸的是,3e9 实际上已被分配,因为它在从基地址 3e8 开始的范围内。因此,这个故事的寓意是在使用 setserial 分配资源之前,请确保您的数据是正确的。

配置文件

虽然 setserial 所做的分配在 PC 断电时会丢失,但配置文件可能会在 PC 重新启动时恢复它们。在较新版本中,您通过 setserial 更改的内容可能会自动保存到配置文件中。当 setserial 运行时,它使用来自配置文件的信息。

此配置文件的位置取决于您的发行版。查看 /etc/ 树中某处的启动脚本(例如 /etc/init.d/ 或 /etc/rc.d/),并阅读“serial”或“setserial”之类的启动脚本。它应该显示配置文件所在的位置。在 Debian 中,有 4 个选项可用于此配置文件

  1. 完全不使用此文件。每次启动时,仅串行驱动程序检测端口,并且 setserial 从不运行。(“kernel”选项)
  2. 保存系统首次关机时 setserial 报告的内容,并将其放入配置文件中。之后,即使有人通过在命令行上运行 setserial 命令然后关闭系统进行了更改,也永远不要对配置文件进行任何更改。(“autosave-once”选项)
  3. 每次关机时,将 setserial 检测到的任何内容保存到配置文件中。(“autosave”选项)
  4. 手动编辑配置文件以设置配置。永远不要对其进行任何自动保存。(“manual”选项)

在过去(可能在 2000 年之前),没有任何配置文件,配置是手动设置(硬编码)在运行 setserial 的 shell 脚本内部的。请参阅 编辑脚本(版本 2.15 之前)

探测

仅当您怀疑端口已被启用(通过 PnP 方法、BIOS、跳线等)时,才使用 setserial 探测端口。否则,setserial 探测永远不会找到它,因为它的地址不存在。问题是软件在指定的 I/O 地址查找端口的位置。在使用“setserial”进行探测之前,可以运行“scanport”(Debian)命令来检查一次扫描中的所有可能端口。它对某些端口上的内容进行粗略猜测,但不确定 IRQ。这是一个快速的初步启动。它可能会使您的 PC 挂起,但到目前为止,它对我来说工作正常。请注意,非 Debian 发行版似乎不提供“scanport”。还有其他扫描程序吗?

使用适当的选项,setserial 可以(在给定的 I/O 地址)探测串行端口,但您必须猜测 I/O 地址。例如,如果您要求它探测 /dev/ttyS2,它只会探测它认为 ttyS2 所在的地址 (2F8)。如果您告诉 setserial ttyS2 位于不同的地址,那么它将在该地址探测,等等。请参阅 探测

此类探测的目的是查看那里是否有 uart,如果有,它的 IRQ 是什么。主要将 setserial 用作最后的手段,因为有更快的方法来尝试它,例如 wvdialconf 检测调制解调器,查看非常早期的启动时消息,或使用 pnpdump --dumpregs 或 lspci -vv。但是,如果您想使用 setserial 检测硬件,请使用例如
setserial /dev/ttyS2 -v autoconfig
如果结果消息显示 uart 类型(例如 16550A),则表示正常。如果相反,它显示 uart 类型的“unknown”,则表示该 I/O 地址根本没有串行端口。一些廉价的串行端口无法正确识别自己,因此如果您看到“unknown”,您可能仍然在那里有一个串行端口。

除了自动探测 uart 类型外,setserial 还可以自动探测 IRQ,但这也不总是有效。在一种情况下,它首先给出了错误的 irq,但是当重复该命令时,它找到了正确的 irq。在 setserial >= 2.15 版本中,您上次探测测试的结果可以自动保存并放入特定于发行版的配置文件中,例如 Debian 的 /etc/serial.conf/etc/sysconfig/serial/var/lib/setserial/autoserial.conf。下次启动 Linux 时将使用它。

可能两个串行端口在硬件中都设置了相同的 IO 地址。当然,这通常不允许用于 ISA 总线,但有时仍然会发生。探测检测到一个串行端口,但实际上有两个。但是,如果它们具有不同的 IRQ,则对 IRQ 的探测可能会显示 IRQ = 0。对我来说,只有当我首先使用 setserial 为 IRQ 提供一个虚构值时,才会发生这种情况。

启动时配置

虽然 setserial 可能会通过初始化脚本运行,但当加载串行模块时(或者当内核启动内置串行驱动程序时,如果它已编译到内核中),也更早地运行类似于 setserial 的程序。因此,当您在屏幕上观看启动时消息时,它可能看起来运行了两次,而实际上确实如此。

如果第一条消息是针对传统端口的,则显示的 IRQ 可能是不正确的,因为它没有探测 IRQ。如果串行端口有第二次报告,则可能是 /etc/init.d/setserial 之类的脚本的结果。它通常不进行探测,因此可能对硬件的实际设置方式有误。它仅显示保存在配置文件中的配置数据。在 setserial 2.15 之前的旧方法是将此类数据直接手动写入脚本。

当内核加载串行模块时(或者如果“模块等效项”内置到内核中),则会检测到所有受支持的 PnP 端口。对于传统 (非 PnP) 端口,仅自动检测 ttyS{0-3},并且驱动程序设置为仅使用 IRQ 4 和 3(无论硬件中实际设置了什么 IRQ)。不进行 IRQ 探测,但可以手动执行此操作。您会看到启动时消息,就像运行了 setserial 一样。

为了纠正 IRQ 中可能存在的错误(或出于其他原因),可能在某处有一个脚本文件运行 setserial。不幸的是,如果此文件中的某些 IRQ 错误,内核仍然具有关于 IRQ 的不正确信息。此文件通常是在启动时完成的初始化的一部分。它是否运行取决于您(和/或您的发行版)如何设置。它也可能取决于运行级别。

在修改配置文件之前,您可以通过在命令行上键入“proposed”setserial 命令来测试它。在某些情况下,当您关闭时,此 setserial 使用的结果将自动保存到某处,例如 /etc/serial.conf(或 autoserial.conf 或 serial)。因此,如果它工作正常(并解决了您的问题),则无需修改任何配置文件。请参阅 使用 /etc/serial.conf 等的配置方法

编辑脚本(版本 2.15 之前需要)

这是在 setserial 2.15 (1999) 之前完成的方式。目标是修改(或创建)/etc 树中的一个脚本文件,该文件在启动时运行 setserial。大多数发行版都提供了这样的文件(但它最初可能没有位于 /etc 树中)。

因此,在版本 2.15 (1999) 之前,它更简单。您所做的只是编辑一个脚本。没有 /etc/serial.conf 文件(或类似的)来配置 setserial。因此,您需要找到在启动时运行“setserial”的文件并对其进行编辑。如果它不存在,您需要创建一个(或将命令放在启动时早期运行的文件中)。如果当前正在使用这样的文件,则它很可能位于 /etc 目录树中的某处。但是 Redhat <6.0 在 /usr/doc/setserial/ 中提供了它,但您需要在使用它之前将其移动到 /etc 树。

过去常用的脚本 /etc/rc.d/rc.serial。Debian 发行版使用 /etc/rc.boot/0setserial。曾经使用的另一个文件是 /etc/rc.d/rc.local,但它可能运行得不够早。据报告,其他进程可能会在 rc.local 运行之前尝试打开串行端口,从而导致串行通信失败。后来,它很可能位于 /etc/init.d/ 中,但通常不打算进行编辑。

如果提供了这样的文件,它很可能包含许多注释掉的示例。通过取消注释其中一些和/或修改它们,您可以正确设置事物。重要的是为 setserial 使用有效路径和有效设备名称。您可以手动执行此文件(只需以超级用户身份键入其名称)进行测试,以查看它是否工作正常。像这样的测试比进行重复重启以使其正确要快得多。

对于版本 >= 2.15(假设您的发行版实现了更改,Redhat 最初没有),这样做可能更棘手,因为在启动时运行 setserial 的文件 /etc/init.d/setserial 或类似文件不打算由用户编辑。请参阅 使用 /etc/serial.conf 等的配置方法

此类脚本中的示例行是

/sbin/setserial /dev/ttyS3 irq 5 uart 16550A  skip_test

或者,如果您希望 setserial 自动确定 ttyS3 的 uart 和 IRQ,您可以使用类似这样的内容

/sbin/setserial  /dev/ttyS3 auto_irq skip_test autoconfig

这是为您要自动配置的每个串行端口完成的,使用您的机器上确实存在的设备名称。在某些情况下,由于硬件原因,它无法正常工作。

使用 /etc/serial.conf 等的配置方法

在 setserial 版本 2.15 (1999) 之前,配置 setserial 的方法是手动编辑在启动时运行 setserial 的 shell 脚本。请参阅 编辑脚本(版本 2.15 之前)。这很简单,但是简单而清晰的方法已更改为不必要的复杂方法。如今,脚本和配置文件是两个不同的文件,而不是一个文件。此 shell 脚本未被编辑,而是从配置文件(例如 /etc/serial.conf(或 /var/lib/setserial/autoserial.conf))获取其数据。

此外,您甚至可能不需要编辑 serial.conf(或类似的),因为在命令行上使用“setserial”命令可能会自动导致 serial.conf 被适当地编辑。这样做是为了您可能不需要编辑任何文件即可设置(或更改)每次 Linux 启动时 setserial 执行的操作。

通常发生的情况是:当您关闭 PC 时,在启动时运行“setserial”的脚本会再次运行,但这次它仅执行“stop”情况的部分所说的操作:它使用“setserial”来找出“setserial”的当前状态,并将该信息放入串行配置文件中,例如 serial.conf。因此,当您运行“setserial”来更改 serial.conf 文件时,它不会立即更改,而只会在您正常关闭时更改。

现在您可能可以猜测可能会出现什么问题。假设您没有正常关闭(有人关闭电源等),并且更改没有保存。假设您使用“setserial”进行实验,并且忘记最后一次运行它以恢复原始状态(或在恢复原始状态时犯了错误)。然后,您的“实验性”设置将被保存。最糟糕的是,除非您知道配置文件中设置了哪些选项,否则您不知道会发生什么。Debian(以及可能的其他发行版)中的一个选项称为“AUTOSAVE-ONCE”,它仅在您首次使用 setserial 命令进行更改时保存更改。

如果设置了选项“###AUTOSAVE###”并且您手动编辑 serial.conf,那么您的编辑将在您关闭时被破坏,因为它将被更改回关闭时 setserial 的状态。有一种方法可以禁用在关闭时更改 serial.conf,即从 serial.conf 的第一行中删除“###AUTOSAVE###”或类似的行。在 Debian 发行版中,在首次安装后首次关闭后,从第一行删除“###AUTOSAVE###”曾经是自动完成的。为了保留这种效果,创建了“AUTOSAVE-ONCE”选项,该选项仅在系统首次关闭时(在您安装或更新 setserial 程序后)执行保存。

现在最常用于在启动时(根据配置文件)运行 setserial 的文件是 /etc/init.d/setserial (Debian) 或 /etc/init.d/serial (Redhat) 或等等,但通常不应编辑它。对于 2.15,Redhat 6.0 仅有一个文件 /usr/doc/setserial-2.15/rc.serial,如果您希望 setserial 在启动时运行,则必须将其移动到 /etc/init.d/。

要禁用端口,请使用 setserial 将其设置为“uart none”。这不会被保存。/etc/serial.conf 的格式似乎与在命令行上的“setserial”之后放置的参数格式相同,每个端口一行。如果您不使用自动保存,则可以手动编辑 /etc/serial.conf。

为了强制将 setserial 设置的当前设置保存到配置文件 (serial.conf) 而无需关闭,请执行通常在您关闭时发生的操作:运行 shell 脚本 /etc/init.d/{set}serial stop。“stop”命令将保存当前配置,但串行端口仍保持正常工作。

在某些情况下,您可能会同时安装旧的和新的配置方法,但希望只有其中一种方法在启动时运行。Debian 将过时的文件标记为“...pre-2.15”。

IRQ

默认情况下,ttyS0 和 ttyS2 将共享 IRQ 4,而 ttyS1 和 ttyS3 共享 IRQ 3。但是,虽然共享串行中断(在运行程序中使用它们)对于 PCI 总线来说是可以的,但对于 ISA 总线来说是不允许的,除非您:1. 拥有内核 2.2 或更高版本,并且 2. 您已编译支持此功能,并且 3. 您的串行硬件支持它。请参阅

中断共享和内核 2.2+

如果您只有两个串行端口 ttyS0 和 ttyS1,那么您仍然没问题,因为非现有设备不存在 IRQ 共享冲突。

如果您添加了传统内部调制解调器(没有即插即用)并保留 ttyS0 和 ttyS1,那么您应该尝试找到未使用的 IRQ 并将其设置在您的串行端口(或调制解调器卡)中,然后使用 setserial 将其分配给您的设备驱动程序。如果 IRQ 5 未用于声卡,则可以将其用于调制解调器。

笔记本电脑:PCMCIA

如果您有笔记本电脑,请阅读 PCMCIA-HOWTO 以获取有关串行配置的信息。对于主板上的串行端口,setserial 的使用方式与桌面计算机相同。但是对于 PCMCIA 卡(例如调制解调器),情况就不同了。PCMCIA 系统的配置应自动运行 setserial,因此您无需运行它。如果您运行它(通过脚本文件或 /etc/serial.conf),它可能会有所不同并导致问题。serial.conf 的自动保存功能不应保存 PCMCIA 卡的任何内容(但 Debian 在 2.15-7 之前是这样做的)。当然,始终可以使用 setserial 来了解驱动程序是如何为 PCMCIA 卡配置的。

11.4 Stty

介绍

stty 完成了串行端口的大部分配置,但由于应用程序(和 getty 程序)通常会处理此问题,因此您可能不需要经常使用它。如果您遇到问题或想查看端口是如何设置的,它会很方便。尝试在您的终端/控制台上键入“stty -a”以查看它现在的设置方式。也可以尝试不带 -a(全部)键入它,以获得一个简短的列表,该列表显示了它的设置与“normal”(即使用命令 “stty sane” 设置的方式)的不同之处。除非您想成为串行历史学家,否则不要尝试学习所有设置,因为许多设置仅适用于 1970 年代的慢速老式哑终端。大多数默认设置应该可以正常工作。

stty 在 man 手册页中进行了文档化,并在 info 页中进行了更详细的说明。键入 “man stty”“info stty”

许多 stty 选项都以“o”(输出)或“i”(输入)开头。例如:onlcr。输出是字节流出计算机,而输入是字节流入计算机。“视角”是计算机,而不是串行端口或连接到串行端口的设备。例如,接收到的输入数据通过电缆进入并到达串行端口芯片。该芯片在将来自串行的位转换为并行表示后,然后将其(通过程序读取)发送到主计算机内存中的大型串行端口缓冲区。因此,芯片既有输入又有输出,但由于它是计算机的输入数据,因此其输出被视为输入。对于流经此芯片的输出,情况类似。“输入”和“输出”是指相对于计算机而不是串行端口硬件(芯片)的流动方向。

setserial 仅处理实际的串行端口,而 stty 既用于串行端口,也用于虚拟终端,例如 PC 显示器上的标准 Linux 文本界面。对于 PC 显示器,许多 stty 设置都是没有意义的。更改波特率等似乎实际上没有任何作用。

以下是 stty 配置的一些项目:速度(位/秒)、校验、位/字节、停止位数、剥离第 8 位?、调制解调器控制信号、流控制、中断信号、行尾标记、更改大小写、填充、缓冲区溢出时发出蜂鸣声?、回显您键入到屏幕的内容、允许后台任务写入终端?、定义特殊(控制)字符(例如按哪个键进行中断)。有关更多详细信息,请参阅 stty man 或 info 页面。另请参阅 man 手册页:termios,它涵盖了 stty 设置的相同选项,但(截至 1999 年中期)涵盖了 stty man 手册页未能提及的功能。

对于某些 getty 实现(getty_ps 包),通常会给 stty 的命令会键入到 getty 配置文件中:/etc/gettydefs。即使没有此配置文件,getty 命令行也可能足以进行设置,因此您不需要 stty。

可以编写 C 程序来更改 stty 配置等。查看其中一些文档可能有助于更好地理解 stty 命令(及其许多可能的参数)的用法。Serial-Programming-HOWTO 可能有用,但已过时。手册页:termios 包含 C 语言结构(类型为 termios)的描述,该结构在计算机内存中存储 stty 配置。此 C 结构中的许多标志名称与 stty 命令的参数几乎相同(并且执行相同的功能)。

流控制选项

要设置硬件流控制,请使用“crtscts”。对于软件流控制,有 3 个设置:ixon、ixoff 和 ixany。

ixany:主要用于终端。在流控制停止后,按任意键将重新启动流。如果您使用“停止滚动”键(或类似的键)停止滚动,则按任意键将恢复滚动。很少需要它,因为再次按“scroll lock”键将执行相同的操作。

ixon:使端口能够侦听 Xoff,并在收到 Xoff 时停止传输。同样,如果收到 Xon,它将恢复传输。

ixoff:使端口能够在主内存中的缓冲区几乎满时,通过传输线发送 Xoff 信号。它可以保护端口所在的设备免受溢出。

对于连接到快速 PC 的慢速哑终端(或其他慢速设备),PC 的端口不太可能溢出。因此,您实际上很少需要启用 ixoff。但通常会“以防万一”启用它。

在“外部”终端使用 stty

如何使用 stty 查看或设置当前正在使用的终端以外的其他终端?如果外部终端正在使用中并且在其上运行 shell,则通常不可能这样做。在其他情况下,例如在另一个终端(如 tty1)上打字时处理 ttyS2,请使用 stty -F /dev/ttyS2 ...(或使用 --file 代替 F)。如果 ... 是 -a,它将显示所有 stty 设置(-a 表示全部)。

但是,如果外部终端(在本例中为 ttyS2)正在运行 shell,那么您看到的内容很可能具有欺骗性,并且尝试设置它将不起作用。虚拟终端也存在此问题,例如从 tty1 处理 tty3 等。请参阅 终端上的两个接口 以了解它。

终端上的两个接口

当使用启用命令行编辑的 shell(例如 bash)时,存在两个不同的终端接口(您在键入 stty -a 时看到的内容)。当您在现代 shell 中的命令行中键入时,您会有一个临时的“原始”接口(或原始模式),其中每个字符都由命令行编辑器在您键入时读取。一旦您按下 <return> 键,命令行编辑器就会退出,并且终端接口会更改为终端的标称“熟”接口(熟模式)。这种熟模式会持续到下一个提示符发送到终端为止(这只是很短的时间)。请注意,永远不会在这种熟模式下键入任何命令,但在原始模式下在命令行上键入的内容会在熟模式下被 shell 读取。

当提示符发送到终端时,终端会从“熟”模式变为“原始”模式(就像您启动编辑器(如 vim)时一样)。提示符表示命令行编辑器开始启动。 “原始”模式的设置仅基于从“熟”模式获取的基本 stty 设置。“原始”模式保留这些设置,但更改其他几个设置以将模式更改为“原始”。它根本不是基于先前“原始”模式中使用的设置。因此,如果使用 stty 更改原始模式的设置,则一旦在据称已“设置”的终端上按下 <return> 键,这些设置将永久丢失。

现在,当键入 stty 以查看终端接口时,可能会看到熟模式或原始模式的视图。您需要弄清楚您正在查看哪一个。如果您从外部终端(而不是您当前正在键入的终端)使用 stty,那么您将看到原始模式设置。所做的任何更改都只会对原始模式进行,并且当有人在您尝试“设置”的外部终端上按下 <return> 键时,这些更改将丢失。但是,如果您键入 stty 命令来查看/更改您正在使用的终端的配置,然后按下 <return> 键,情况就不同了。 <return> 将终端置于熟模式。您的更改将被保存,并且当终端返回原始模式时仍然存在(当然,除非它是原始模式下不允许的设置)。

这种情况可能会造成问题。例如,假设您损坏了终端接口。要恢复它,您可以转到另一个终端并“stty -F dev/ttyS1 sane”(或类似的命令)。这将不起作用!当然,您可以尝试在已损坏的终端上键入“stty sane ...”,但您看不到您键入的内容。以上所有内容不仅适用于哑终端,也适用于 PC 显示器上使用的虚拟终端以及 X 中的终端窗口。换句话说,它几乎适用于所有使用 Linux 的人。

幸运的是,当您启动 Linux 时,任何在启动时运行 stty 的文件都可能处理没有 shell 在其上运行的终端(或没有终端的串行端口),因此对于这种特殊情况没有问题。

在哪里放置 stty 命令?

如果您需要每次计算机启动时都让 stty 设置串行接口,那么您需要将 stty 命令放在每次计算机启动(Linux 启动)时都会执行的文件中。它应该在串行端口被使用之前运行(包括在端口上运行 getty)。有很多可能的地方可以放置它。如果它被放在多个地方,而您只知道(或记得)其中一个地方,那么很可能会发生冲突。因此,请务必记录您所做的事情。

一种放置它的地方是在系统启动时运行 setserial 的同一个文件中。位置取决于发行版和版本。最好将其放在 setserial 命令之后,以便首先完成底层操作。如果您在 /etc 树中有目录,其中每个文件都在启动时执行(System V Init),那么您可以为此目的创建一个名为“stty”的文件。

过时的重定向方法

在 2000 年左右之前,如果您想在外部终端上使用 stty,则需要使用重定向运算符“<”。例如,要在 tty1 上坐在 ttyS2 上使用 stty,您将键入:stty .... < /dev/ttyS2。在 2000 年之后(前提是您的 setserial 版本 >= 1.17 且 stty >= 2.0),创建了一种更好的方法,使用 -F 选项:stty -F /dev/ttyS2。当旧的重定向方法失败时,这将起作用。

上面的旧重定向示例使 ttyS2 成为 stty 的标准输入。这为 stty 程序提供了指向“文件”ttyS2 的链接,以便它可以“读取”它。但是,它不是像人们可能期望的那样读取发送到 ttyS2 的字节,而是使用该链接来查找端口的配置设置,以便它可以读取或更改它们。在过去,有些人试图使用 ``stty ... > /dev/ttyS2'' 来设置终端。这不起作用。相反,它会获取 stty 命令为您所在终端(例如 tty1)正常显示的消息,并将此消息发送到 ttyS2。但它不会更改 ttyS2 的任何设置。

这是旧的重定向运算符的一个问题(如果您改用较新的 -F 选项,则不会发生这种情况)。有时,当尝试使用 stty 时,命令会挂起并且没有任何反应(即使在按下 <return> 键后,您也不会获得下一个命令的提示符)。这很可能是由于端口被卡住,因为它正在等待其中一个调制解调器控制线被置为有效。例如,除非您已将“clocal”设置为忽略调制解调器控制线,否则如果没有 CD 信号被置为有效,端口将不会打开,并且 stty 将无法用于它(除非您使用较新的 -F 选项)。硬件流控制似乎也存在类似的情况。如果端口的电缆甚至没有需要置为有效的引脚的导体,那么就无法轻易阻止挂起。

解决上述挂起问题的一种方法是使用较新的 -F 选项并根据需要设置“clocal”和/或“crtscts”。如果您没有 -F 选项,您可以尝试在端口上运行一些程序(例如 minicom),这将强制它即使控制线指示不这样做也进行操作。然后希望此程序可以设置端口,使其将来不需要控制信号即可打开:clocal 或 -crtscts。要使用“minicom”执行此操作,您可能必须重新配置 minicom,然后退出并重新启动它。与其进行所有这些麻烦,不如简单地重新启动 PC,或者通过使用虚拟终端使用“top”(或“ps”获取进程号,然后使用“kill”杀死该进程)来杀死该进程。

过时的重定向方法(在较新版本中仍然有效)是键入 ``stty ... < /dev/ttyS2''。如果使用 -F 的新方法有效,但过时的方法挂起,则意味着端口由于调制解调器控制线未被置为有效而挂起。因此,过时的重定向方法可能仍然对故障排除有用。

11.5 什么是 isapnp?

isapnp 是一个用于配置 ISA 总线上的即插即用 (PnP) 设备(包括内置调制解调器)的程序。它包含在名为“isapnptools”的软件包中,并且包含另一个程序“pnpdump”,该程序可以查找所有 ISA PnP 设备,并以可以添加到 PnP 配置文件 /etc/isapnp.conf 的格式向您显示用于配置它们的选项。 isapnp 命令可以放入启动文件中,以便在每次启动计算机时运行,从而配置 ISA PnP 设备。即使您的 BIOS 不支持 PnP,它也能够执行此操作。请参阅 Plug-and-Play-HOWTO。

11.6 通过串行端口将两台 PC 连接在一起

这是在两台 PC 的串行端口之间运行串行电缆(交叉类型 = null-modem 类型)的地方。那么如何使用这条线路呢?一种方法是让一台 PC 在串行线上运行登录,而另一台 PC 运行例如 minicom 或 picocom 来模拟终端。请参阅 Text-Terminal-HOWTO。在这种情况下,不使用网络协议,也没有错误检测。

另一种方法是在该线路上运行网络协议。例如,要将 PPP 与 TCP/IP 结合使用,请参阅 Serial Laplink HOWTO。尽管此 HOWTO 没有提及旧程序“slattach”(串行线连接),但它可以将串行线置于使用您选择的协议的网络模式。 slattach 的协议包括 PPP 或 SLIP(PPP 之前广泛使用的较旧协议)。

Debian 软件包 net-tools 包含 slattach。 SLIP 作为内核模块提供,也可以构建到内核中(2.2、2.4 或 2.6)。

11.7 将串行端口连接到快速网络:ser2net

ser2net 是一个 Linux 程序,它将网络连接到串行端口。例如,有人通过以太网端口或快速调制解调器(例如 telnet)连接到您的 PC。然后(没有 ser2net),他们可以远程登录到您的 PC,然后在您的 PC 上运行使用 PC 上的串行端口的程序。但是,如果他们不需要登录和使用您的软件,而是可以立即连接到串行端口,可能会更好。在您的 PC 上运行的 ser2net 可以实现这一点。

它可能就像以太网电缆和串行电缆之间的桥梁。以太网电缆上将具有 TCP/IP 协议,但串行端口将仅具有从 TCP/IP 数据包中提取的原始数据。可选地,您也可以在串行线上使用 TCP/IP 数据包。由于以太网端口具有高带宽,因此它可以同时与多个串行端口通信,并且还可以让数据在其他地方流动。

要设置 ser2net,您必须指定哪些网络端口(在以太网上)将连接到哪些串行端口。然后,当网络数据包通过以太网到达您的 PC,并且这些数据包寻址到您已绑定到串行端口的网络端口时,这些数据包中的数据将流向串行端口。反之亦然。当然,网络不一定是以太网。它可以是电缆调制解调器或 DSL 线路等。


下一页 上一页 目录