什么是串口流量控制?
串口通信中,流量控制(Flow Control)是一种协调发送端与接收端数据传输速率的机制。当发送端的数据传输速度高于接收端的处理速度时,如果不加控制,接收端的缓冲区将会溢出,导致数据丢失。流量控制通过暂停和恢复数据流来防止这种情况发生。
串口流量控制主要分为两大类:硬件流控(Hardware Flow Control)使用RS-232接口中的专用信号线(如RTS和CTS)来实现;软件流控(Software Flow Control)则通过在数据流中插入特殊字符(XON/XOFF)来协调传输。此外还有DTR/DSR流控方式,但在实际应用中较为少见。
硬件流控:RTS与CTS工作原理
RTS/CTS信号定义
在RS-232标准中,RTS(Request to Send,请求发送)和CTS(Clear to Send,允许发送)是两条专用的硬件握手信号线。在标准的DB9串口连接器中,RTS对应第7脚,CTS对应第8脚;在DB25连接器中则分别是第4脚和第5脚。
RTS由数据终端设备(DTE,如计算机或串口卡)驱动,CTS由数据通信设备(DCE,如调制解调器或工业仪表)驱动。两者的电压逻辑与数据线相反:控制线有效(断言)时为+3V至+15V,无效(取消断言)时为-3V至-15V。
现代RTS/CTS流控的工作流程
在早期的RS-232规范中,RTS的含义是"请求获得发送许可",CTS则是"允许发送"。但在现代点对点串口通信中,RTS/CTS被重新解释为双向流量控制信号——每端通过自己的输出信号线告知对方自己的接收缓冲区状态:
- 当接收端有可用缓冲区空间时,驱动RTS线为有效状态(高电平),表示"我可以接收数据"。
- 发送端检测到CTS线有效时,继续发送数据;如果CTS线变为无效(低电平),发送端暂停发送。
- 当接收端处理完缓冲区中的数据、重新有空间时,再次断言RTS,发送端检测到CTS恢复有效后继续发送。
这种机制在设备驱动层面由UART硬件直接处理,无需软件干预,响应速度极快。接收端可以在一个字符时间内完成流控信号的切换。
DTR/DSR流控
DTR(Data Terminal Ready,数据终端就绪)和DSR(Data Set Ready,数据设备就绪)是另一对信号线。DTR由DTE驱动(DB9第4脚),DSR由DCE驱动(DB9第6脚)。它们主要用于指示设备已上电并处于可用状态,"握手"意味更浓而非实时流控。部分早期系统将DTR/DSR用作流控信号,但由于其响应较慢且缺乏UART层面的硬件支持,现代系统中很少用于实时流量控制。
软件流控:XON/XOFF工作原理
XON与XOFF字符定义
软件流控(又称XON/XOFF流控)使用数据通道内的特殊ASCII字符来控制数据流,不需要额外的信号线。XOFF(Transmit Off,暂停发送)使用ASCII码19(DC3字符,十六进制13),键盘快捷键为Ctrl+S。XON(Transmit On,恢复发送)使用ASCII码17(DC1字符,十六进制11),键盘快捷键为Ctrl+Q。
XON/XOFF的起源可追溯到Teletype Model 33 ASR电传打字机,其将ASCII设备控制字符DC1和DC3分别用作XON和XOFF,这一用法后来成为事实标准并被广泛沿用至今。
XON/XOFF工作机制
当接收端的缓冲区即将填满时,它通过发送通道向发送端发送XOFF字符。发送端收到XOFF后暂停数据发送。待接收端处理完缓冲区中的数据后,发送XON字符,发送端检测到XON后恢复数据发送。
这种机制可以双向工作:通信双方都可以发送XON/XOFF来控制对方的数据流。例如,一台计算机向慢速打印机发送数据时,打印机在缓冲区接近填满时发送XOFF,计算机暂停发送;打印机处理完数据后发送XON,计算机恢复发送。
Robust XON(稳健XON)机制
为防止因通信错误导致XOFF被误接收后通信永久挂起,部分设备实现了Robust XON机制。接收端在空闲且可接收数据时,每隔1至30秒发送一次XON字符,确保不会因意外XOFF导致通信永久中断。HP LaserJet II等串行打印机即采用了这一机制。
硬件流控与软件流控的关键对比
可靠性
硬件流控使用带外信号(独立物理线),流控信号与数据通道完全隔离,不受传输数据内容的影响,具有最高的可靠性。软件流控使用带内信号,XON/XOFF字符与普通数据共享同一通道,存在以下可靠性问题:
- XOFF字符需要至少一个字符时间传输,可能被已排队的数据延迟。
- 当UART的FIFO缓冲区启用时,接收端可能来不及在缓冲区溢出前发送XOFF。标准16550 UART的16字节FIFO在高速通信中尤其容易出现问题。
- 传输二进制数据时,数据字节0x11或0x13可能被误判为流控字符,导致通信异常。需要采用转义机制来避免这一问题。
对比总结如下表所示:
| 特性 | 硬件流控(RTS/CTS) | 软件流控(XON/XOFF) | On-Chip软件流控 |
|---|---|---|---|
| 数据完整性 | 最高 | 良好(FIFO关闭)/ 不可靠(FIFO开启) | 良好 |
| 所需信号线数 | 5线(TX/RX/GND/RTS/CTS) | 3线(TX/RX/GND) | 3线 |
| 带外/带内 | 带外(独立物理线) | 带内(数据通道内) | 带内 |
| 响应延迟 | 微秒级(硬件直接处理) | 毫秒级(需软件处理) | 微秒级(UART固件处理) |
| 二进制数据兼容性 | 完全兼容 | 需转义处理0x11/0x13 | 需转义处理 |
线缆要求
硬件流控需要至少5根信号线(TX、RX、GND、RTS、CTS),因此需要完整的RS-232连接线缆。软件流控仅需3根线(TX、RX、GND),在只使用三线制串口连接时是唯一可选的流控方式。这也是软件流控在早期计算机和低端设备中广泛使用的原因——减少线缆数量和连接器引脚数可以显著降低成本。
UART兼容性要求
标准16550 UART的16字节FIFO在软件流控模式下存在风险:接收端在FIFO接近填满时发送XOFF,但由于FIFO中已有数据排队,XOFF发送前可能又接收了更多数据导致溢出。解决方式包括:
- 关闭UART的FIFO功能(降低性能但保证可靠)。
- 使用支持On-Chip软件流控的高级UART,如16750或16950系列,这些UART在硬件层面自动监视数据流中的XON/XOFF字符,无需软件介入。
- 在低速通信(如9600bps及以下)中,软件流控配合适当缓冲区可以有效工作。
工控场景下的流控选择建议
优先使用硬件流控
在工业控制环境中,当串口通信使用标准RS-232接口且有完整的信号线连接时,强烈建议启用RTS/CTS硬件流控。原因包括:
- 工业环境中的电磁干扰不会破坏带外流控信号的有效性。
- 高速通信(9600bps以上)时,硬件流控的响应延迟远低于软件流控。
- 传输二进制数据(固件升级、配置参数、采集数据)时无需担心XON/XOFF字符冲突。
RS-422/485的流控方案
RS-422和RS-485接口使用差分信号传输,没有RTS/CTS等效信号线。在这类半双工(RS-485)或全双工多点(RS-422)通信中,通常有两种方式处理流控:
- 软件层面的流控:在通信协议中实现应答确认机制(如Modbus协议的请求-响应模式本身就是一种应用层流控)。
- 使能XON/XOFF软件流控:适用于全双工RS-422的点对点连接,但同样面临二进制数据兼容性问题。
- 使用RS-232转485转换器:部分转换器将RS-232侧的RTS/CTS信号映射为RS-485的方向控制信号,实现自动收发切换。
流控的常见配置方法
Windows系统配置
在Windows设备管理器中,打开串口端口的"属性"→"端口设置"→"流控制"选项,可选择"硬件"(RTS/CTS)、"XON/XOFF"或"无"。建议9600bps及以上使用"硬件"流控。DTR/DSR流控作为"硬件"的子选项存在于部分驱动中,但较少使用。
Linux系统配置
Linux下使用stty命令配置串口流控:
# 启用硬件流控(RTS/CTS) stty -F /dev/ttyS0 crtscts # 启用软件流控(XON/XOFF) stty -F /dev/ttyS0 ixon ixoff # 关闭流控 stty -F /dev/ttyS0 -crtscts -ixon -ixoff
Linux内核标准采用RTS/CTS作为串口的默认硬件流控方案。
流控故障排查常见问题
数据截断或字符丢失
最常见的原因是一端启用了流控而另一端未启用。当接收端缓冲区满时,通过RTS/CTS或XOFF发送暂停信号,但发送端未配置相应的流控检测,继续发送数据导致丢失。
通信挂死
使用软件流控时,如果传输二进制数据包含0x11或0x13字节,接收端可能将其误判为XON/XOFF。另一种可能是XOFF字符因线路噪声损坏未能被正确识别,导致发送端持续等待。启用Robust XON机制或在协议层面增加超时重传可以缓解。
线缆问题
硬件流控依赖RTS/CTS信号线的物理连接。使用三线制串口线(仅TX/RX/GND)时硬件流控无法工作。排查时应确认线缆连接了完整的RS-232信号,通常可以使用串口环回测试验证。
总结
串口流量控制是保证串口通信可靠性的关键技术。硬件流控(RTS/CTS)具有响应快、可靠性高、不影响数据内容的优势,是工控场景下的首选方案;软件流控(XON/XOFF)的优势在于仅需三线连接,适用于线缆受限的环境,但存在二进制数据兼容性和FIFO溢出风险。在实际应用中,应根据接口类型、通信速率、数据内容和线缆条件选择合适的流控方式,并确保通信两端配置一致。