下一页 上一页 目录

18. 什么是 UART?它们如何影响性能?

18.1 UART 简介

UART(送器)是你 PC 主板(或内置调制解调器卡)上的串行芯片。UART 功能也可以在执行其他功能的芯片上完成。在较旧的计算机(如许多 486 计算机)上,芯片位于磁盘 IO 控制器卡上。更老的计算机有专用的串行接口卡。

当 PC 都采用并行总线架构时,UART 的目的是将来自 PC 并行总线的字节转换为串行比特流。从串行端口出来的电缆是串行的,每种流向只有一个线。串行端口每次发送一个比特的比特流。相反,通过外部电缆进入串行端口的比特流被转换为计算机可以理解的并行字节。UART 处理字节大小的数据块,这也很方便地与 ASCII 字符的大小相同。

假设你的终端连接到 PC 上的串行端口。当你输入一个字符时,终端将该字符提供给其发送器(也是一个 UART)。发送器以特定的速率,每次一位地将该字节发送到串行线上。在 PC 端,接收 UART 获取所有比特并重建字节(在较旧的 PC 上是并行的),并将其放入缓冲区中。对于可能具有 PCI-e 串行端口的新型 PC,UART 不需要进行并行到串行的转换,因为 PCI-e“总线”已经是串行线路。但是 PCI-e 线路承载着编码信号,必须对其进行解码,然后大大减速到 RS-232 串行线路的速度。

除了在串行和并行之间进行转换外,UART 还作为其主要任务的副产品(副作用)执行其他一些操作。用于表示比特的电压也被转换(更改)。在传输之前,每个字节都会添加额外的比特(称为起始位和停止位)。有关详细信息,请参阅 Serial-HOWTO 部分 电压波形。此外,虽然计算机内部并行总线上的流速(字节/秒)非常高,但 UART 串行端口侧的流速要低得多。UART 具有一组固定的速率(速度),它可以在其串行端口接口上使用。

18.2 两种类型的 UART

UART 主要有两种基本类型:哑 UART 和 FIFO UART。哑 UART 是 8250、16450、早期 16550 和早期 16650。它们已经过时,但是如果你了解它们的工作原理,就很容易理解现代的 FIFO UART(晚期 16550、16550A 和更高型号)是如何工作的。请注意,所有这些驱动程序在 Linux 中仍然被标记为“8250”驱动程序,如果你编译自己的内核等,你可能会在编译选项中看到它。

关于 16550 存在一些混淆。早期型号存在缺陷,只能作为 16450(无 FIFO)正常工作。后来修复了缺陷的型号被命名为 16550A,但许多制造商不接受名称更改,并继续称其为 16550。如今使用的大多数 16550 都类似于 16550A。即使你的硬件手册(或标签注释)说它是 16550,Linux 也会将其报告为 16550A。16650 也存在类似的情况(只是更糟,因为据称制造商不承认有任何问题)。Linux 会将晚期 16650 报告为 16650V2。如果它报告为 16650,那是个坏消息,只能像它有一个字节缓冲区一样使用。

18.3 FIFO

要理解哑 FIFO(先进先出队列规则)之间的区别,首先让我们检查当 UART 发送或接收一个字节时会发生什么。UART 本身无法处理通过它的数据,它只是接收和发送数据。对于过时的哑 UART,每次发送或接收一个字节时,CPU 都会从串行设备收到中断。然后,CPU 将接收到的字节从 UART 的缓冲区移出并放入内存中的某个位置,或者给 UART 另一个要发送的字节。过时的 8250 和 16450 UART 只有一个字节缓冲区。这意味着,每次发送或接收 1 个字节时,CPU 都会被中断。在低传输速率下,这还可以。但是,在高传输速率下,CPU 会忙于处理 UART,以至于没有时间充分处理其他任务。在某些情况下,CPU 没有及时处理中断,并且字节被覆盖,因为它们进入的速度太快。这称为“溢出”或“溢出”。

FIFO UART 有助于解决这个问题。16550A(或 16550)FIFO 芯片配备 16 字节 FIFO 缓冲区。这意味着它可以接收最多 14 个字节(或发送 16 个字节),然后才需要中断 CPU。它不仅可以等待更多字节,而且 CPU 可以一次传输所有(14 到 16 个)字节。与只有 1 字节缓冲区的过时 UART 相比,这是一个显着的优势。CPU 接收的中断更少,并且可以自由地执行其他操作。数据很少丢失。请注意,FIFO 缓冲区的中断阈值(触发级别)可以设置为小于 14。1、4 和 8 是其他可能的选择。截至 2000 年末,Linux 用户无法直接设置这些值(setserial 无法做到)。虽然许多 PC 只有带有 16 字节缓冲区的 16550,但更好的 UART 具有更大的缓冲区。

请注意,中断是在缓冲区即将满之前(例如,对于 16 字节缓冲区,在“触发级别”为 14 字节时)发出的。这为在中断服务例程能够实际获取所有这些字节之前接收更多字节留出了空间。触发级别可以由内核软件设置为各种允许的值。触发级别为 1 将几乎像过时的 UART(除了它在发出中断后仍有空间容纳 15 个字节)。

现在考虑你在 Internet 上的情况。它刚刚向你发送了一个简短的文本网页。所有这些都是通过串行端口传入的。如果你的串行端口上有 16 字节的缓冲区,该缓冲区会保留字符,直到它有 14 个字符,那么屏幕上最后几个字符可能会丢失,因为 FIFO 缓冲区等待获取第 14 个字符。但是第 14 个字符没有到达,因为你已经收到了整个页面(通过电话线),并且没有更多字符要发送给你。可能是最后这些字符是 HTML 格式等的一部分,而不是要在屏幕上显示的字符,但你也不想丢失格式。

有一个“超时”来防止上述问题。“超时”对于接收 UART 缓冲区的工作方式如下:如果字符一个接一个地到达,那么只有当例如第 14 个字符到达缓冲区时才会发出中断。但是,如果一个字符到达,而下一个字符没有在此后不久到达,则无论如何都会发出中断。这导致获取 FIFO 缓冲区中的所有字符,即使只有几个(或只有一个)字符存在。发送缓冲区也有“超时”。

18.4 为什么 FIFO 缓冲区很小

你可能想知道为什么 FIFO 缓冲区不大。毕竟,内存很便宜,使用千字节范围内的缓冲区不会花费更多。原因是流量控制。流量控制在必要时停止串行线上的数据(字节)流。如果向串行端口发送停止信号,则停止请求由软件处理(即使流量控制是“硬件”)。串行端口硬件对流量控制一无所知。

如果串行端口缓冲区在收到停止发送的流量控制信号时包含 64 个准备发送的字节,它仍将发送这 64 个字节,从而违反停止请求。由于它不知道流量控制,因此无法阻止它。如果缓冲区很大,那么将发送更多字节,从而违反流量控制的停止请求。

18.5 UART 型号

以下是一些 UART 的列表。TL

对于 V.90 56k 调制解调器,使用 16650 可能会快几个百分点(特别是当您下载大型未压缩文件时)。16650 的主要优势在于其更大的缓冲区大小,因为除非调制解调器压缩率很高,否则不需要额外的速度。一些 56k 内置调制解调器可能配备 16650 ??

非 UART 和智能多端口板使用 DSP 芯片进行额外的缓冲和控制,从而更进一步地减轻 CPU 的负担。例如,Cyclades Cyclom 和 Stallion EasyIO 板使用 Cirrus Logic CD1400 RISC UART,许多板使用 80186 CPU 甚至特殊的 RISC CPU 来处理串行 IO。

许多 486 PC(旧)和所有奔腾(或类似的)都应该至少有带有 FIFO 的 16550A(通常简称为 16550)。今天(2000 年)一些更好的主板甚至配备了 16650。有关在 1990 年之前的硬件中用更新的 UART 替换过时的 UART,请参阅附录:过时 ...


下一页 上一页 目录