串行和 UART 教程
摘要
本文讨论了在 FreeBSD 上使用串行硬件。
1. UART:它是什么以及它是如何工作的
版权所有 ® 1996 Frank Durda IV <uhclem@FreeBSD.org> ,保留所有权利。1996 年 1 月 13 日。
通用异步收发器(UART)控制器是计算机串行通信子系统的关键组件。UART 接收数据字节并以顺序方式传输各个位。在目的地,第二个 UART 将这些位重新组装成完整的字节。
串行传输通常用于调制解调器以及计算机、终端和其他设备之间的非网络通信。
串行传输有两种主要形式:同步和异步。根据硬件支持的模式,如果支持异步通信,通信子系统的名称通常会包含 A ,如果支持同步通信,则包含 S 。以下介绍了这两种形式。
一些常见的缩写词是:
通用异步收发器/发送器 UART
通用同步异步收发器/发送器 USART
1.1. 同步串行传输
同步串行传输要求发送方和接收方彼此共享时钟,或者发送方提供一个 strobe 或其他定时信号,以便接收方知道何时“读取”数据的下一位。在大多数形式的串行同步通信中,如果在特定时刻没有可用的数据进行传输,必须发送填充字符,以便始终传输数据。同步通信通常更高效,因为只有数据位在发送方和接收方之间传输,如果需要额外的布线和电路来共享发送方和接收方之间的时钟信号,则同步通信可能更昂贵。
打印机和固定磁盘设备使用一种同步传输形式,其中数据发送在一组线路上,而时钟或 strobe 则发送在另一根线路上。打印机和固定磁盘设备通常不是串行设备,因为大多数固定磁盘接口标准为每个时钟或 strobe 信号发送一个完整的数据字,通过使用每个字位的单独线路。在 PC 行业中,这些被称为并行设备。
PC 中的标准串行通信硬件不支持同步操作。这种模式仅在此进行比较描述。
1.2. 异步串行传输
异步传输允许数据在发送方无需向接收方发送时钟信号的情况下进行传输。 相反,发送方和接收方必须事先达成有关时序参数的协议,并且在每个字中添加特殊位,用于同步发送和接收单元。
当单词被发送到用于异步传输的 UART 时,一个称为“起始位”的比特被添加到要发送的每个单词的开头。 起始位用于向接收方发出警报,表明即将发送数据字,并强制接收器中的时钟与发送器中的时钟同步。 这两个时钟必须足够准确,以便在剩余比特的传输过程中频率漂移不超过 10%。(这一要求是在机械电传打字机时代设定的,对于现代电子设备来说很容易满足。)
在起始位之后,将发送数据字的各个位,最低有效位(LSB)先发送。传输中的每个位都将以与其他位完全相同的时间发送,并且接收方在每个位指定的时间周期的中间点左右观测电线,以确定该位是 0 还是 1。例如,如果每个位需要发送两秒钟,接收方将在一秒钟后检查信号,以确定它是 0 还是 1,然后等待两秒钟,再检查下一个位的值,依此类推。
发送方不知道接收方何时查看位的值。发送方只知道时钟何时指示开始传输字的下一个位。
当整个数据字发送完成后,发送方可以添加由发送方生成的奇偶校验位。接收方可以使用奇偶校验位进行简单的错误检查。然后发送方将发送至少一个停止位。
当接收方接收到数据字中的所有位时,它可以检查奇偶校验位(发送方和接收方必须就是否使用奇偶校验位达成一致意见),然后接收方寻找停止位。如果停止位没有在应出现的时间出现,UART 将认为整个单词已损坏,并在读取数据单词时向主机处理器报告传输错误。传输错误的通常原因是发送方和接收方时钟未同步,或者信号被中断。
无论数据是否被正确接收,UART 都会自动丢弃起始位、奇偶校验位和停止位。如果发送方和接收方配置相同,这些位将不会传递到主机。
如果另一个字已准备好传输,则新字的起始位可以在上一个字的停止位发送后立即发送。
由于异步数据是“自同步”的,如果没有数据传输,传输线路可以空闲。
1.3. 其他 UART 功能
除了将数据从并行转换为串行进行传输和在接收时从串行转换为并行的基本工作外,UART 通常还会提供额外的电路来指示传输媒体的状态,并在远程设备未准备好接受更多数据时调节数据流。例如,当连接到 UART 的设备是调制解调器时,调制解调器可能会报告电话线上是否有载波信号,而计算机则可以通过升高或降低这些额外信号之一来指示调制解调器重置或不接听电话。这些额外信号的功能在 EIA RS232-C 标准中有定义。
1.4. RS232-C 和 V.24 标准
在大多数计算机系统中,UART 连接到遵循 EIA RS232-C 规范的信号产生电路。还有一个名为 V.24 的 CCITT 标准,与 RS232-C 中包含的规范相似。
1.4.1. RS232-C 比特分配(标记和空格)
在 RS232-C 中,数值 1 被称为 Mark ,而数值 0 被称为 Space 。当通信线路空闲时,该线路被称为“标记”,或者传输连续的 1 数值。
起始位始终具有数值 0 (空格)。停止位始终具有数值 1 (标记)。这意味着在每个字的开头,线路上始终会有一个从标记(1)到空格(0)的转变,即使连续传输多个字。这保证了发送方和接收方可以重新同步他们的时钟,无论数据位的内容是什么。
停止位和起止位之间的空闲时间不需要是通信链路位率的精确倍数(包括零),但大多数 UART 都是为简单起见设计成这样的。
在 RS232-C 中,“Marking”信号(一个 1 )由-2 VDC 至-12 VDC 的电压表示,而“Spacing”信号(一个 0 )由 0 至+12 VDC 的电压表示。发射机应发送+12 VDC 或-12 VDC,接收机应允许长电缆中的一些电压损耗。一些低功耗设备(如便携式计算机)的发送机有时仅使用+5 VDC 和-5 VDC,但只要电缆长度短,这些数值对 RS232-C 接收器仍然可接受。
1.4.2. RS232-C 中断信号
RS232-C 还规定了一种称为 Break 的信号,它是通过发送连续的 Spacing 值(没有起始或结束位)而引起的。当数据电路上没有电流时,认为该线路正在发送 Break 。
信号必须持续时间长于发送完整字节加上起始位、停止位和奇偶校验位所需的时间。大多数 UART 可以区分帧错误和中断信号,但如果 UART 无法执行此操作,帧错误检测可用于识别中断信号。
在电报打印机时代,当全国各地的多台打印机被串联连接(比如新闻服务),任何一个单位都可以通过暂时打开整个电路,使电流不流动来引发中断。这被用于允许具有紧急新闻的位置中断当前正在发送信息的其他位置。
在现代系统中,有两种类型的中断信号。如果中断信号持续时间超过 1.6 秒,则被视为“调制解调器中断”,某些调制解调器可以在检测到该信号时编程终止对话并摘机或进入调制解调器的命令模式。如果中断信号持续时间小于 1.6 秒,则表示数据中断,远程计算机需对该信号作出响应。有时候这种形式的中断被用作提醒或中断信号,有时被接受为 ASCII 控制字符 CONTROL-C 的替代品。
标记和空格在纸带系统中也等同于“孔”和“无孔”。
中断不能由纸带或任何其他字节值生成,因为字节总是与起始位和停止位一起发送。UART 通常能够响应来自主处理器的特殊命令生成连续的间隔信号。
1.4.3. RS232-C DTE 和 DCE 设备
RS232-C 规范定义了两种类型的设备:数据终端设备(DTE)和数据载波设备(DCE)。通常,DTE 设备是终端(或计算机),DCE 是调制解调器。在对话的另一端,通过电话线接收信号的调制解调器也是 DCE 设备,连接到该调制解调器的计算机是 DTE 设备。DCE 设备在 DTE 设备发送信号的引脚上接收信号,反之亦然。
当两个都是 DTE 或都是 DCE 的设备必须在没有调制解调器或类似介质转换器的情况下连接在一起时,必须使用空调制解调器。空调制解调器会在电气上重新排列电缆,使发射器输出连接到另一设备的接收器输入,反之亦然。所有控制信号也进行类似的转换,使每个设备都能看到来自另一设备的 DCE(或 DTE)信号。
DTE 和 DCE 设备生成的信号数量是不对称的。DTE 设备为 DCE 设备生成的信号比 DTE 设备从 DCE 设备接收到的信号少。
1.4.4. RS232-C 引脚分配
EIA RS232-C 规范(及其等同的 ITU V.24)要求使用二十五针连接器(通常为 DB25),并定义了该连接器中大多数引脚的用途。
在 IBM 个人计算机和类似系统中,通过九针连接器(DB9)提供了一部分 RS232-C 信号。PC 连接器上未包含的信号主要涉及同步操作,而 IBM 为 IBM PC 选择的 UART 不支持这种传输模式。
根据计算机制造商的不同,DB25、DB9 或这两种类型的连接器可能被用于 RS232-C 通信。(IBM PC 还使用 DB25 连接器用于并行打印机接口,这造成了一些混淆。)
下面是 DB25 和 DB9 连接器中 RS232-C 信号分配的表格。
1
-
AA
101
PG/FG
-
框架/保护接地
2
3
BA
103
TD
DTE
传输数据
3
2
BB
104
RD
DCE
收到数据
4
7
CA
105
RTS
DTE
请求发送
5
8
CB
106
CTS
DCE
准备发送
6
6
CC
107
DSR
DCE
数据集已准备好
7
5
AV
102
SG/GND
-
信号地
8
1
CF
109
DCD/CD
DCE
数据载波检测
9
-
-
-
-
-
保留供测试
10
-
-
-
-
-
预留用于测试
11
-
-
-
-
-
预留用于测试
12
-
CI
122
SRLSD
DCE
线路信号检测器
13
-
SCB
121
SCTS
DCE
次要发送就绪
14
-
SBA
118
STD
DTE
次要发送数据
15
-
DB
114
TSET
DCE
传输信号元件定时
16
-
SBB
119
SRD
DCE
次级接收数据
17
-
DD
115
RSET
DCE
接收器信号元素定时
18
-
-
141
LOOP
DTE
本地环回
19
-
SCA
120
SRS
DTE
次级发送请求
20
4
CD
108.2
DTR
DTE
数据终端就绪
21
-
-
-
RDL
DTE
远程数字回环
22
9
CE
125
RI
DCE
振铃指示器
23
-
CH
111
DSRS
DTE
数据信号速率选择器
24
-
DA
113
TSET
DTE
传输信号元件定时
25
-
-
142
-
DCE
测试模式
1.5. 比特,波特和符号
波特是异步通信中传输速度的测量单位。由于调制解调器通信技术的进步,这个术语在描述新设备的数据速率时经常被误用。
传统上,波特率表示实际发送到媒体上的比特数,而不是实际从一个 DTE 设备移动到另一个设备的数据量。波特计数包括发送 UART 生成并由接收 UART 移除的起始位、停止位和奇偶校验位的开销比特。这意味着,实际上,七位数据字需要传输 10 位。因此,如果使用奇偶校验位并且存在一个起始位和一个停止位,一个能够从一个地方移动 300 位每秒的调制解调器通常只能移动 30 个 7 位字。
如果使用 8 位数据字和奇偶校验位,数据率将降至 27.27 字每秒,因为现在发送八位字需要 11 位,并且调制解调器仍然每秒发送 300 位。
将每秒字节转换为波特率或反之的公式在纠错调制解调器出现之前是简单的。这些调制解调器从主机计算机的 UART 接收位流(即使使用内部调制解调器,数据仍经常被序列化),并将位转换为字节。然后,这些字节被合并成数据包,并使用同步传输方法通过电话线发送。这意味着,被 DTE(计算机)中的 UART 添加的起始、停止和奇偶校验位在发送调制解调器发送之前被接收调制解调器移除。当这些字节被远程调制解调器接收时,远程调制解调器将起始、停止和奇偶校验位添加到字中,将它们转换为串行格式,然后将它们发送到远程计算机中的接收 UART,然后远程计算机去除起始、停止和奇偶校验位。
进行这些额外转换的原因是为了让两个调制解调器可以执行错误校正,这意味着接收调制解调器能够要求发送调制解调器重新发送未接收到正确校验和的数据块。这种检查由调制解调器处理,DTE 设备通常不知道这个过程正在发生。
通过去掉起始、停止和奇偶校验位,两个调制解调器必须在它们之间共享的用于错误校正的额外数据位大多被隐藏在发送和接收 DTE 设备看到的有效传输速率之外。例如,如果一个调制解调器发送十个 7 位字给另一个调制解调器而不包括起始、停止和奇偶校验位,发送调制解调器将能够添加 30 位自己的信息,接收调制解调器可以使用这些信息进行错误校正,而不影响实际数据的传输速度。
Baud 这个术语的使用因执行压缩的调制解调器而进一步混淆。通过电话线传递的单个 8 位字可能代表传输给发送调制解调器的十几个字。接收调制解调器将把数据扩展回原始内容,并将这些数据传递给接收的 DTE。
现代调制解调器还包括缓冲区,允许跨电话线(DCE 到 DCE)的比特移动速率与在对话两端的 DTE 和 DCE 之间的比特移动速率不同。通常,由于调制解调器使用压缩,DTE 和 DCE 之间的速度比 DCE 到 DCE 的速度更高。
由于在两个机器之间传输过程中描述一个字节所需的比特数量不同,加上 DTE-DCE 和 DCE-DCE 链接上使用的比特每秒速率不同,用 Baud 这个术语来描述总体通信速度会引起问题,并可能误导实际传输速度。因此,比特每秒(bps)是描述 DCE 到 DCE 接口处传输速率的正确术语,而当两个系统通过有线连接建立连接时,或使用不执行错误校正或压缩的调制解调器时,Baud 或比特每秒是可接受的术语。
现代高速调制解调器(2400、9600、14400 和 19200bps)实际上仍然以或低于 2400 波特(更准确地说,2400 符号每秒)运行。高速调制解调器能够使用称为星座填充的技术将更多的数据比特编码到每个符号中,这就是为什么调制解调器的有效比特每秒速率更高,但调制解调器继续在电话系统提供的有限音频带宽内运行。运行在 28800 及更高速度的调制解调器具有可变的符号速率,但技术是相同的。
1.6. IBM 个人计算机 UART
从最初的 IBM 个人计算机开始,IBM 选择了国家半导体 INS8250 UART 用于 IBM PC Parallel/Serial 适配器。来自 IBM 和其他供应商的兼容计算机的后续世代继续使用 INS8250 或国家半导体 UART 家族的改进版本。
1.6.1.IBM UART 家族树
有多个版本和后续的 INS8250 UART 代。每个主要版本在下面描述。
INS8250 此部件用于原始的 IBM PC 和 IBM PC/XT。该部件的原始名称是 INS8250 ACE(异步通信元件),它采用 NMOS 技术制造。
8250 使用八个 I/O ports,具有一个字节发送和一个字节接收缓冲区。这个原始的 UART 有几个竞争条件和其他缺陷。原始的 IBM BIOS 包含代码来解决这些缺陷,但这使得 BIOS 依赖于这些缺陷的存在,因此像 8250A、16450 或 16550 这样的后续部件不能在原始的 IBM PC 或 IBM PC/XT 中使用。
这是采用 NMOS 技术制造的 INS8250 的较慢速度版本。它具有与原始 INS8250 相同的问题。
INS8250A 是 INS8250 的改进版本,使用 XMOS 技术,纠正了各种功能缺陷。INS8250A 最初被供应商用于 PC 克隆计算机,这些供应商使用了“干净”的 BIOS 设计。由于芯片中的更正,此部件无法与与 INS8250 或 INS8250B 兼容的 BIOS 一起使用。
这是 INS8250A 的 CMOS 版本(低功耗),具有类似的功能特性。
与 NS8250A 相同,但改进使其可以与更快的 CPU 总线设计一起使用。IBM 在 IBM AT 中使用了这个部件,并更新了 IBM BIOS,不再依赖于 INS8250 中的错误。
NS16C450 这是 NS16450 的 CMOS 版本(低功耗)。
与 NS16450 相同,具有 16 字节发送和接收缓冲区,但该缓冲区设计存在缺陷,无法可靠地使用。
NS16550A 与 NS16550 相同,但纠正了缓冲区缺陷。由于其在操作系统中能够可靠地处理较高的数据速率,而操作系统中断响应时间较慢,因此 16550A 及其后续产品已成为 PC 行业中最流行的 UART 设计。
NS16C552 这个组件由两个单独封装在一起的 NS16C550A CMOS UART 组成。
PC16550D 与 NS16550A 相同,但纠正了一些细微缺陷。这是 16550 系列的 D 修订版,也是国半公司最新的设计。
1.6.2. NS16550AF 和 PC16550D 是相同的东西
几年前,National 重组了他们的零件编号系统,NS16550AFN 这个名字不再存在。(如果你有一个 NS16550AFN,看看零件上的日期代码,这是一个通常以九开头的四位数。前两位数字是年份,后两位是该年零件包装的周数。如果你有一个 NS16550AFN,它可能已经有几年了。)
新的编号类似于 PC16550DV,后缀字母有轻微的差异,具体取决于封装材料及其形状。(下面可以找到编号系统的描述。)
重要的是要明白,在某些商店,你可能会为 1990 年生产的 NS16550AFN 支付 15 美元(US),而在下一个箱子里是带有次要修复的新 PC16550DN 部件,自 AFN 部件生产以来,National 已经做出了这些修复,PC16550DN 可能是在过去六个月内生产的,它的成本是 NS16550AFN 的一半(批量价低至 5 美元(US)),因为它们随时可用。
随着 NS16550AFN 芯片供应的持续缩减,价格可能会继续上涨,直到更多人发现并接受 PC16550DN 实际上具有与旧部件编号相同的功能。
1.6.3. 国家半导体部件编号系统
较老的 NS nnnnnrqp 零件号现在的格式为 PC nnnnnrgp 。
r 是修订字段。National Semiconductor 的 16550 当前修订版是 D 。
p 是封装类型字段。类型有:
N
DIP
直插式双列直引脚封装
V
LPCC
J 形引脚塑料芯片载体
g 是产品等级字段。如果 I 出现在包类型字母之前,表示这是一个“工业”级别的部件,其规格高于标准部件但不如军用规范(Milspec)组件。这是一个可选字段。
所以我们以前称为 NS16550AFN(DIP 包)的东西现在叫做 PC16550DN 或 PC16550DIN。
1.7. 其他供应商和类似的 UARTs
多年来,8250、8250A、16450 和 16550 已被其他芯片供应商许可或复制。在 8250、8250A 和 16450 的情况下,确切的电路(“megacell”)被许可给许多供应商,包括西部数据和英特尔。其他供应商对该部件进行了反向工程或生产了具有类似行为的仿真器。
在内置调制解调器中,调制解调器设计人员经常会使用调制解调器微处理器模拟 8250A/16450,而模拟的 UART 经常具有由几百个字节组成的隐藏缓冲区。由于缓冲区的大小,这些仿真可以像 16550A 一样可靠地处理高速数据。然而,大多数操作系统仍然会报告 UART 仅为 8250A 或 16450,并且除非使用特殊驱动程序,否则不能有效利用仿真 UART 中的额外缓冲区。
一些调制解调器制造商受市场力量驱使,放弃具有数百字节缓冲区的设计,而改为使用 16550A UART,以便产品在市场比较中得到有利对比,尽管这一举动可能降低了有效性能。
一个常见的误解是所有标有“16550A”的部件在性能上都是相同的。实际上,这些 16550A 克隆中存在差异,有些甚至存在明显的缺陷。
当 NS16550 开发出来时,国家半导体公司获得了该设计的多项专利,他们还限制了许可,使其他供应商更难提供具有类似功能的芯片。由于这些专利的存在,反向工程设计和仿真必须避免侵犯专利所涵盖的权利要求。因此,这些副本几乎从未能完全与 NS16550A 或 PC16550D 相同,而后者是大多数计算机和调制解调器制造商希望购买但有时不愿支付所需价格以获取正品的部件。
克隆 16550A 部件的一些差异并不重要,而另一些差异可能会导致设备在特定操作系统或驱动程序下无法使用。这些差异可能会在使用其他驱动程序时出现,或者在发生特定事件组合时出现,这些事件在 Windows® 驱动程序中没有得到充分测试或考虑。这是因为大多数调制解调器供应商和 16550 克隆制造商使用 Windows® for Workgroups 3.11 和 Microsoft® MS-DOS® 实用程序中的 Microsoft 驱动程序作为与 NS16550A 兼容性的主要测试标准。这种过于简化的标准意味着如果使用不同的操作系统,由于克隆和正品之间的细微差异,可能会出现问题。
美国国家半导体公司提供了一个名为 COMTEST 的程序,该程序执行独立于任何操作系统驱动程序的兼容性测试。应该记住,这类程序的目的是展示竞争对手产品的缺陷,因此该程序会报告主要以及极其细微的行为差异。
在本文件作者于 1994 年进行的一系列测试中,使用 COMTEST 测试了美国国家半导体公司、德州仪器、StarTech 和 CMD 制造的组件以及嵌入内部调制解调器的巨型单元和仿真。以下列出了一些这些组件的差异计数。由于这些测试是在 1994 年进行的,因此它们可能无法反映供应商当前产品的性能。
应当注意,COMTEST 通常在检测到过多数量或某些类型的问题时会中止。在本次测试中,COMTEST 被修改为无论遇到多少差异都不会中止。
National
(PC16550DV)
0
National
(NS16550AFN)
0
National
(NS16C552V)
0
TI
(TL16550AFN)
3
CMD
(16C550PE)
19
StarTech
(ST16C550J)
23
Rockwell
具有内部 16550 或仿真器的参考调制解调器(RC144DPi/C3000-25)
117
Sierra
带有内部 16550(SC11951/SC11351)的调制解调器
91
到目前为止,本文档的作者还没有发现任何使用 COMTEST 程序报告零差异的非 National 零件。还应注意,National 多年来有五个版本的 16550,最新的零件与被认为是功能基准的经典 NS16550AFN 的行为略有不同。即使在 National 零件的 A、B 和 C 版本中存在官方错误描述时,COMTEST 似乎对 National 产品线内的差异视而不见,并且在 National 零件上报告没有错误(除了原始的 16550),因此必须考虑到 COMTEST 中的这种偏差。
重要的是要明白,简单地计算来自 COMTEST 的差异数量并不能揭示哪些差异重要,哪些不重要。例如,列出的两个内部有 UART 的调制解调器中,大约一半的差异是由于克隆 UART 不支持五位和六位字符模式。真正的 16550、16450 和 8250 UART 都支持这些模式,而 COMTEST 检查这些模式的功能,所以报告了五十多个差异。然而,几乎没有现代调制解调器支持五位或六位字符,尤其是那些具有纠错和压缩功能的调制解调器。这意味着与五位和六位字符模式相关的差异可以忽略。
COMTEST 报告的许多差异都与时间有关。在许多克隆设计中,当主机从一个 port 读取时,某些其他 port 中的状态位可能不会在相同的时间内更新(有些更快,有些更慢),与真正的 NS16550AFN 不同,而 COMTEST 寻找这些差异。这意味着差异的数量可能具有误导性,因为某个设备可能只有一两个差异,但它们非常严重,而另一个设备的状态寄存器更新速度比参考部件快或慢(这可能永远不会影响正确编写的驱动程序的操作)可能会报告数十个差异。
COMTEST 可用作筛选工具,提醒管理员存在可能导致问题或需要特殊处理的潜在不兼容组件。
如果你在一个内置调制解调器的 16550 上运行 COMTEST,或者调制解调器连接到串口 port,你需要首先向调制解调器发送 ATE0&W 命令,这样调制解调器就不会回显任何测试字符。如果你忘记这样做,COMTEST 至少会报告一个差异:
1.8. 8250/16450/16550 寄存器
8250/16450/16550 UART 占据了八个连续的 I/O port 地址。在 IBM PC 中,这八个 ports 有两个定义的位置,它们被统称为 COM1 和 COM2。PC 克隆和附加卡的制造商创建了两个额外的区域,称为 COM3 和 COM4,但这些额外的 COM ports 会与某些系统上的其他硬件冲突。最常见的冲突是与提供 IBM 8514 仿真的视频适配器冲突。
COM1 位于 0x3f8 至 0x3ff,通常使用 IRQ 4。COM2 位于 0x2f8 至 0x2ff,并通常使用 IRQ 3。COM3 位于 0x3e8 到 0x3ef,没有标准的 IRQ。COM4 位于 0x2e8 到 0x2ef,没有标准的 IRQ。
下面提供了 8250/16450/16550 UART 的 I/O ports 的描述。
+0x00
写入 (DLAB==0)
传输保持寄存器 (THR)。 写入此 port 的信息被视为数据字,并将由 UART 传输。
+0x00
读取 (DLAB==0)
接收缓冲寄存器 (RBR). UART 接收的任何数据字被主机通过读取此 port 访问。
+0x00
写/读(DLAB==1)
分频锁存器 LSB(DLL) 这个值将从主输入时钟(在 IBM PC 上,主时钟为 1.8432MHz)中分频,所得时钟将决定 UART 的波特率。这个寄存器保存除数的位 0 到 7。
+0x01
写入/读取 (DLAB==1)
除数锁存器 MSB (DLH) 该数值将被从主输入时钟(在 IBM PC 中,主时钟为 1.8432MHz)中除去,得到的时钟将确定 UART 的波特率。这个寄存器保存除数的第 8 至 15 位。
+0x01
写/读 (DLAB==0)
中断启用寄存器 (IER) 8250/16450/16550 UART 将事件分类成四类。每个类别可以配置为在任何事件发生时生成中断。8250/16450/16550 UART 生成单个外部中断信号,无论启用类别中发生了多少事件。由主机处理器来响应中断,然后轮询启用的中断类别(通常所有类别都启用中断),以确定中断的真正原因。 第 7 位 → 保留,始终为 0。 第 6 位 → 保留,始终为 0。 位 5 → 保留,总是 0。 位 4 → 保留,总是 0。 位 3 → 启用调制解调器状态中断(EDSSI)。将此位设置为“1”时,当一个或多个状态线发生变化时,UART 会生成一个中断。 位 2 → 启用接收线路状态中断 (ELSI) 将此位设置为“1”会导致 UART 在检测到输入数据中的错误(或中断信号)时生成中断。 位 1 → 启用发送保持寄存器空中断 (ETBEI) 将此位设置为“1”会导致 UART 在有一个或多个要传输的字符空间时生成中断。 位 0 → 启用接收数据可用中断 (ERBFI) 将此位设置为“1”会导致 UART 在接收到足够字符超过 FIFO 触发级别、FIFO 计时器到期(过期数据)或禁用 FIFO 时接收到单个字符时生成中断。
+0x02
写
FIFO 控制寄存器 (FCR) (此 port 不存在于 8250 和 16450 UART 中。) 第 7 位 → 接收器触发位 #1 第 6 位 → 接收器触发位 #0 这两位控制接收器在 FIFO 活动时何时生成中断。 在生成中断之前接收到多少个字 0 0 1 0 1 4 1 0 8 1 1 14 位 5 → 保留,总是 0。 位 4 → 保留,总是 0。 位 3 → DMA 模式选择。如果位 0 设置为“1”(启用 FIFO),设置此位将使 -RXRDY 和 -TXRDY 信号的操作从模式 0 更改为模式 1。 位 2 → 发送 FIFO 重置。当该位写入“1”时,FIFO 的内容将被丢弃。任何当前正在传输的字将完整发送。此功能在中止传输时非常有用。 位 1 → 接收 FIFO 重置。当该位写入“1”时,FIFO 的内容将被丢弃。任何当前在移位寄存器中组装的字将完整接收。 位 0 → 16550 FIFO 启用。设置时,发送和接收 FIFO 均被启用。当 FIFO 启用或禁用时,保持寄存器、移位寄存器或 FIFO 中的任何内容都会丢失。
+0x02
读取
中断标识寄存器 位 7 → 启用 FIFO。在 8250/16450 UART 上,此位为零。 位 6 → 启用 FIFO。在 8250/16450 UART 上,此位为零。 位 5 → 保留,始终为 0。 位 4 → 保留,始终为 0。 位 3 → 中断 ID 位#2。在 8250/16450 UART 上,此位为零。 位 2 → 中断 ID 位 #1 位 1 → 中断 ID 位 #0。这三个位结合在一起报告导致当前中断发生的事件类别。这些类别具有优先级,因此如果多个事件类别同时发生,UART 将优先报告更重要的事件,主机必须按照报告的顺序解决这些事件。所有导致当前中断的事件必须解决完毕后才会生成新的中断。(这是 PC 架构的限制。) 2 1 0 优先级 描述 0 1 1 第一次接收到错误 (OE, PE, BI 或 FE) 0 1 0 第二次接收到可用数据 1 1 0 第二次触发电平识别 (接收缓冲区中的陈旧数据) 0 0 1 第三个发射器可以容纳更多单词 (THRE) 0 0 0 第四个调制解调器状态变化 (-CTS, -DSR, -RI, 或 -DCD) Bit 0 → 中断待决位。如果此位设置为 "0",则至少有一个中断待决。
+0x03
写/读
行控制寄存器 (LCR) 第 7 位 → 除数锁存访问位 (DLAB)。设置时,数据发送/接收寄存器 (THR/RBR) 和中断使能寄存器 (IER) 的访问将被禁用。任何对这些 ports 的访问现在都将重定向到除数锁存寄存器。设置此位、加载除数寄存器并清除 DLAB 应在中断禁用的情况下完成。 第 6 位 → 设置中断。设置为“1”时,发送器开始传输连续的间隔,直到此位设置为“0”。这将覆盖正在传输的字符的任何位。 第 5 位 → 固定奇偶校验。当启用奇偶校验时,设置此位将导致奇偶校验始终为“1”或“0”,取决于第 4 位的值。第 4 位 → 偶校验选择 (EPS)。当启用奇偶校验且第 5 位为“0”时,设置此位将导致发送和接收偶校验。否则,将使用奇校验。 位 3 → 奇偶校验启用 (PEN)。当设置为 "1" 时,奇偶校验位插入在数据的最后一位和停止位之间。UART 还将期望接收到的数据中存在奇偶校验。 位 2 → 停止位数 (STB)。如果设置为 "1" 并使用 5 位数据字,每个数据字传输和期望 1.5 个停止位。对于 6、7 和 8 位数据字,传输和期望 2 个停止位。当此位设置为 "0" 时,每个数据字使用一个停止位。 位 1 → 字长选择位 #1 (WLSB1) 位 0 → 单词长度选择位 #0 (WLSB0) 这些位共同指定了每个数据字中的位数。 1 0 字长 0 0 5 数据位 0 1 6 数据位 1 0 7 数据位 1 1 8 数据位
+0x04
写/读
调制解调器控制寄存器(MCR) 位 7 → 保留,始终为 0。 位 6 → 保留,始终为 0。 第 5 位 → 保留,始终为 0。 第 4 位 → 回环使能。当设置为“1”时,UART 发射器和接收器内部连接在一起,以允许诊断操作。此外,UART 调制解调器控制输出连接到 UART 调制解调器控制输入。CTS 连接到 RTS,DTR 连接到 DSR,OUT1 连接到 RI,OUT 2 连接到 DCD。 第 3 位 → OUT 2。主机处理器可以设置为高或低的辅助输出。在 IBM PC 串行适配器(及大多数克隆)中,OUT 2 用于三态(禁用)8250/16450/16550 UART 的中断信号。 位 2 → OUT 1。主处理器可以设置为高或低的辅助输出。在 IBM PC 串行适配器上不使用此输出。 位 1 → 请求发送 (RTS)。当设置为 "1" 时,UART -RTS 线路的输出为低 (有效)。 位 0 → 数据终端准备好 (DTR)。当设置为 "1" 时,UART -DTR 线路的输出为低 (有效)。
+0x05
写/读
行状态寄存器 (LSR) 位 7 → 接收器 FIFO 错误。在 8250/16450 UART 上,此位为零。当 FIFO 中的任何字节出现以下任意一种或多种错误情况时,此位被置为“1”:PE、FE 或 BI。 位 6 → 发送器空 (TEMT)。当置为“1”时,发送 FIFO 或发送移位寄存器中没有剩余的字。发送器完全空闲。 位 5 → 发送保持寄存器空 (THRE)。当置为“1”时,FIFO(或保持寄存器)现在至少有一个额外的字可以传输。发送器在此位被置为“1”时可能仍在发送。 位 4 → 中断中断 (BI)。接收器检测到中断信号。 位 3 → 帧错误 (FE)。检测到起始位,但停止位未在预期时间出现。接收到的字可能被篡改。 位 2 → 奇偶校验错误 (PE)。接收到的字的奇偶校验位不正确。 位 1 → 溢出错误(OE)。收到一个新字,但接收缓冲区没有空间。位于移位寄存器中的新到达字被丢弃。对于 8250/16450 串口,保持寄存器中的字被丢弃,并将新到达字放入保持寄存器。 位 0 → 数据准备就绪(DR)。接收缓冲区中有一个或多个主机可以读取的字。在此位设置之前,一个字必须完全接收并从移位寄存器移至缓冲区(或对于 8250/16450 设计,移至保持寄存器)。
+0x06
写/读
调制解调器状态寄存器(MSR) 位 7 → 数据载波检测(DCD)。反映了 UART 上 DCD 线路的状态。 位 6 → 环指示器 (RI)。反映 UART 上 RI 线的状态。 位 5 → 数据设置就绪 (DSR)。反映 UART 上 DSR 线的状态。 位 4 → 清除发送 (CTS)。反映 UART 上 CTS 线的状态。 位 3 → 数据载波检测差分(DDCD)。如果-DCD 线自上次主机读取 MSR 以来已经改变状态一次以上,则设置为“1”。 位 2 → 尾缘环指示器(TERI)。如果-RI 线自上次主机读取 MSR 以来已经经历过低电平到高电平的转变,则设置为“1”。 位 1 → 数据集就绪差分(DDSR)。如果-DSR 线自上次主机读取 MSR 以来已经改变状态一次以上,则设置为“1”。 位 0 → Delta 清除发送 (DCTS)。如果 -CTS 线自上次主机读取 MSR 以来状态再次发生变化,则设置为 "1"。
+0x07
写入/读取
Scratch 寄存器(SCR)。该寄存器在 UART 中不执行任何功能。主机可以将任何值写入此位置,并在稍后由主机读取。
1.9. 超越 16550A UART
尽管 National Semiconductor 未提供任何与 16550 兼容且提供额外功能的组件,但其他各种供应商已经提供了一些组件。以下介绍了一些这些组件。需要理解的是,为了有效利用这些改进,可能需要由芯片供应商提供驱动程序,因为大多数流行的操作系统不支持 16550 提供的功能之外的特性。
ST16650 由於這個部件與 NS16550A 相似,但可以選擇啟用擴展的 32 字節發送和接收緩衝區。由 StarTech 製造。
TIL16660 默認情況下,此部分的行為類似於 NS16550A,但可以選擇啟用擴展的 64 字節發送和接收緩衝區。由德州儀器製造。
Hayes ESP 這款專有的插件卡包含一個 2048 字節的發送和接收緩衝區,並支持高達 230.4Kbit/sec 的數據速率。由 Hayes 製造。
除了这些“哑”UART 之外,许多厂商还生产智能串行通信板。这种设计通常提供一个与多个 UART 接口的微处理器,处理和缓冲数据,并在必要时提醒主 PC 处理器。由于 UART 在这种通信系统中不直接由 PC 处理器访问,厂商不需要使用与 8250、16450 或 16550 UART 兼容的 UART。这使得设计者可以自由选择可能具有更好性能特征的组件。
2. 配置 sio 驱动程序
sio 驱动程序提供对基于 NS8250、NS16450、NS16550 和 NS16550A 的 EIA RS-232C(CCITT V.24)通信接口的支持。还支持几种多端口卡。详细的技术文档请参阅 sio(4)手册页。
2.1. Digi International (DigiBoard) PC/8
由 Andrew Webster <awebster@pubnix.net> 贡献。1995 年 8 月 26 日。
这是一个配置片段,来自一台带有 Digi International PC/8 和 16550 的机器。它有 8 个调制解调器连接到这 8 条线上,工作得很好。不要忘记添加 options COM_MULTIPORT ,否则它不会很好地工作!
设置这个的诀窍在于标志的最高位代表上一次 SIO port,在这种情况下是 11,因此标志是 0xb05。
2.2. Boca 16
贡献者 Don Whiteside <whiteside@acm.org> 。1995 年 8 月 26 日。
制作 Boca 16 port 板卡与 FreeBSD 兼容的过程非常简单,但你需要一些东西来使它工作:
你需要安装内核源码以便重新编译必要的选项,或者你需要别人为你编译。2.0.5 默认内核不启用多端口支持,无论如何你都需要为每个 port 添加设备条目。
其次,你需要知道 Boca 板卡的中断和 IO 设置,以便在内核中正确设置这些选项。
重要提示- Boca 16 的实际 UART 芯片位于连接器盒中,而不在内部主板上。因此,如果你将其拔下,那些 ports 的探针会失败。我从未测试过断开盒子然后将其重新插入并启动,我建议你也不要这样做。
如果你尚未设置自定义内核配置文件,请参考 FreeBSD 手册的内核配置章节了解一般程序。以下是针对 Boca 16 板的具体事项,假定你正在使用内核名称 MYKERNEL,并使用 vi 进行编辑。
添加该行
到配置文件。
在当前的 device sion 行处,你需要添加 16 个设备。以下示例是针对一个中断为 3、基 IO 地址为 100h 的 Boca 板。每个 port 的 IO 地址是从前一个 port 加 8 个十六进制数,因此是 100h、108h、110h……地址。
除非你使用完全相同的 sio 分配,否则必须更改 flags 条目。标志根据 0x MYY 设置,其中 M 表示主 port 的次要编号(最后一个 port 在 Boca 16 上),YY 表示是否启用 FIFO(启用)、是否使用 IRQ 共享(是)以及是否有 AST/4 兼容的 IRQ 控制寄存器(否)。在这个例子中,
指示主 port 是 sio16。如果我添加另一个板,并分配 sio17 到 sio28,则该板上的所有 16 个 ports 的标志将为 0x1C05,其中 1C 表示主 port 的次要编号。不要改变 05 设置。
保存并完成内核配置,重新编译,安装并重新启动。假设你已成功安装了重新编译的内核,并已将其设置为正确的地址和 IRQ,则你的引导消息应指示成功探测到 Boca ports 如下:(显然 sio 号码,IO 和 IRQ 可能不同)
如果消息显示得太快以至于看不清楚,
会显示引导消息。
接下来,必须使用/dev/MAKEDEV 脚本为设备制作适当的条目。如果你正在运行具有 devfs(5)支持编译的内核的 FreeBSD 5.X,则可以省略此步骤。如果你确实需要创建/dev 条目,请按照以下内容操作:
如果由于某种原因你不想要或不需要呼叫设备,可以不制作 cua*设备。
如果你想快速而草率地确保设备正常工作,你可以简单地将调制解调器插入每个 port(作为 root 用户)。
对于你制作的每个设备。你应该看到每个正常 port 的 RX 指示灯闪烁。
2.3. 支持廉价的多 UART 卡
由 Helge Oldach hmo@sep.hamburg.com 贡献,1999 年 9 月
你是否曾想过关于 FreeBSD 支持你的 20 美元多 I/O 卡,带有两个(或更多)COM ports,共享 IRQs?以下是解决方法:
通常,支持此类板卡的唯一选项是为每个 port 使用不同的 IRQ。例如,如果你的 CPU 板上有一个内置的 COM1 port(又名 sio0-I/O 地址 0x3F8 和 IRQ 4),你有一个带有两个 UART 的扩展板,通常需要将它们配置为 COM2(又名 sio1-I/O 地址 0x2F8 和 IRQ 3),以及第三个 port(又名 sio2)作为 I/O 0x3E8 和 IRQ 5。显然,这是对 IRQ 资源的浪费,因为基本上应该能够在前几节中描述的配置中使用单个 IRQ 运行两个扩展板 ports。
这种便宜的 I/O 板通常有一个 4x3 跳线矩阵用于 COM ports,类似于下图:
这里显示的是 port A 接线到 IRQ 5 和 port B 接线到 IRQ 3。你特定板上的 IRQ 列可能会有所不同——其他板可能为 IRQs 3、4、5 和 7 提供跳线。
可以得出结论,使用手工制作的覆盖 IRQ 3 列中所有三个连接点的跳线将两个 ports 接线到 IRQ 3 会解决问题,但事实并非如此。你不能复制 IRQ 3,因为每个 UART 的输出驱动器都以“图腾柱”方式连接,所以如果其中一个 UART 驱动 IRQ 3,输出信号将不会如你所期望的那样。根据扩展板或主板的实现,IRQ 3 线将一直保持高电平或始终保持低电平。
你需要将两个 UART 的 IRQ 驱动程序解耦,这样,只有当两个 UART 中的一个断言 IRQ 时,板的 IRQ 线才会上升,并且否则保持低电平。 Joerg Wunsch 提出了解决方案 j@ida.interface-business.de:焊接由两个二极管(强烈建议使用 Germanium 或 Schottky 类型)和一个 1 kOhm 电阻组成的有线"或"。这是从上面的 4x3 跳线字段开始的原理图:
二极管的阴极与一个共同点连接,以及一个 1 kOhm 下拉电阻。连接电阻至地是至关重要的,以避免总线上的 IRQ 线悬空。
现在我们已经准备好配置内核。继续使用这个示例,我们将配置:
注意,sio1 和 sio2 的 flags 设置确实至关重要;有关详细信息,请参阅 sio(4)。(通常,“flags”属性中的 2 指的是 sio 2 ,其中包含 IRQ,你肯定希望为 5 低四位。)打开内核详细模式后,这应产生类似于以下内容:
尽管/sys/i386/isa/sio.c 在使用上有点神秘,使用上面的“irq maps”数组,基本思想是你在第一、第三和第四位置观察到 0x1 。这意味着相应的 IRQ 在输出时被设置并在之后被清除,这正是我们所期望的。如果你的内核不显示这种行为,则很可能是你的连线有问题。
3. 配置 cy 驱动程序
由 Alex Nash 贡献。1996 年 6 月 6 日。
Cyclades 多端口卡基于 cy 驱动程序,而不是其他多端口卡使用的常规 sio 驱动程序。配置很简单:
将 cy 设备添加到内核配置中(请注意,你的 irq 和 iomem 设置可能有所不同)。
重建并安装新内核。
通过键入以下命令来创建设备节点(以下示例假设一个 8-port 板):
如果适用,通过复制串行设备( ttyd )条目并使用 ttyc 替换 ttyd 来将拨号条目添加到/etc/ttys 中。例如:
使用新内核重新启动。
4. 配置 si 驱动程序
由 Nick Sayer <nsayer@FreeBSD.org> 贡献。1998 年 3 月 25 日。
Specialix SI/XIO 和 SX 多端口卡使用 si 驱动程序。单台机器最多可以有 4 个主机卡。支持以下主机卡:
ISA SI/XIO 主机卡(2 个版本)
EISA SI/XIO 主机卡
PCI SI/XIO 主机卡
ISA SX 主机卡
PCI SX 主机卡
虽然 SX 和 SI/XIO 主机卡看起来有很大不同,但它们的功能基本上是相同的。主机卡不使用 I/O 位置,而是需要 32K 内存块。ISA 卡的出厂配置将其放在 0xd0000-0xd7fff 。它们还需要一个 IRQ。PCI 卡当然会自动配置。
你可以连接最多 4 个外部模块到每个主机卡。外部模块包含 4 个或 8 个串行 ports。它们有以下几种类型:
SI 4 或 8 个 port 模块。每个 port 支持的最大速率为 57600 bps。
XIO 8 port 模块。每个 port 支持最高 115200 bps。一种类型的 XIO 模块有 7 个串行和 1 个并行 port。
SXDC 8 port 模块。每个 port 支持最高 921600 bps。与 XIO 类似,一个模块也可用一种并行 port。
要配置 ISA 主机卡,请将以下行添加到你的内核配置文件中,并根据需要更改数字:
对于 SX ISA 主机卡,有效的中断请求号为 9、10、11、12 和 15,对于 SI/XIO ISA 主机卡为 11、12 和 15。
要配置 EISA 或 PCI 主机卡,请使用该行:
在添加配置项之后,重新构建并安装你的新内核。
以下步骤,在使用 FreeBSD 5.X 中的 devfs(5)时不必要。
在使用新内核重新启动后,你需要在/dev 目录中创建设备节点。MAKEDEV 脚本会为你处理这个问题。计算你有多少个 ports,然后输入:
(其中 nn 是 ports 的数量)
如果你想在这些 ports 上显示登录提示,你需要向/etc/ttys 添加类似这样的行:
更改终端类型为适当的。对于调制解调器, dialup 或 unknown 都可以。
最后更新于