串口编程/数据包的形成
串口编程: 介绍和 OSI 网络模型 -- RS-232 布线和连接 -- 典型 RS232 硬件配置 -- 8250 UART -- DOS -- MAX232 驱动/接收器系列 -- Windows 中的 TAPI 通信 -- Linux 和 Unix -- Java -- Hayes 兼容调制解调器和 AT 命令 -- 通用串行总线 (USB) -- 数据包的形成 -- 错误校正方法 -- 双向通信 -- 数据包恢复方法 -- 串行数据网络 -- 实用应用程序开发 -- IP 通过串行连接
几乎所有关于计算机之间通信的想法都涉及“数据包”,尤其是在涉及到超过两台计算机的情况下。
这个想法非常类似于将支票放入信封中寄给电力公司。我们把要发送给特定计算机的数据(“支票”)放在一个“信封”里,这个信封包含特定计算机的地址。
数据包从一个前导码开始,接着是头信息,然后是原始数据,最后用一些额外的字节用于传输相关的错误检测信息——通常是一个 Fletcher-32 校验和。我们将在下一章 串口编程/错误校正方法 中详细讨论如何处理这些错误检测信息。
电力公司的会计在收到支票后会扔掉信封。她已经知道她自己公司的地址了。但这是否意味着信封的“开销”毫无用处?不。
同样地,一旦一台计算机收到数据包,它会立即扔掉前导码。如果计算机看到数据包的地址是它自己,并且没有错误,那么它会丢弃包装并保留数据。
头信息包含所有路由器和交换机用来将完整的数据包发送到正确目标地址的目标地址信息,就像纸质信封上写着邮递员用来将邮件发送到正确目标地址的目标地址一样。大多数协议使用一个头信息,像大多数纸质邮件信封一样,还包括源地址和一些其他传输相关信息。
不幸的是,数据包有几十种略微不同、不兼容的协议,因为人们选择略微不同的方式来表示地址信息和错误检测信息。
…… 不兼容协议之间的网关 ……
协议设计人员根据许多权衡选择最大和最小数据包大小。
- 数据包应该“小”以防止一个发射机发送一个长数据包来占用网络。
- 数据包应该“小”以便单个错误可以通过重新传输一个小数据包而不是一个大数据包来纠正。
- 数据包应该“大”以便更多时间用于传输好数据,更少时间用于开销(前导码、头信息、尾信息、后导码和数据包间隙)。
- 数据包头信息和尾部信息应该很短,以减少开销。
- 尾部信息应该包含一个大的错误检测码字字段,因为一个较短的码字更容易错误地接受一个错误严重的数据包(我们将在下一章 ../错误校正方法/ 中更详细地讨论错误检测)。
- 使数据包头信息稍微长一些,以便有意义的字段落在字节或字边界上,而不是高度编码的位字段,使 CPU 更容易解释它们,从而允许更低成本的网络硬件。
- 使数据包头信息稍微长一些——而不是一个涵盖整个数据包的单个错误检测字段,我们有一个用于头信息的错误检测字段,另一个用于数据的错误检测字段——允许一个节点立即拒绝一个在目标地址或长度字段中出现位错误的数据包,避免不必要的处理。相同的 CRC 多项式用于两者。这种只涵盖头信息的“额外”CRC 在几种文件格式中使用[1]——它是 MPEG 音频文件格式的可选功能[2][3][4],gzip 格式的可选功能等等。
- 固定大小的数据包——所有数据包都属于几个长度类别——不需要“长度”字段,简化缓冲区分配,但在您想发送不是固定数据大小的精确倍数的数据时,会浪费“内部”数据空间来填充最后一个数据包。
不幸的是,任何通信协议都无法拥有所有这些理想的功能
- 透明度:数据通信是透明的,并且是“8 位干净”的——(a) 任何可能的数据文件都可以传输,(b) 文件中的字节序列始终被视为数据,而绝不会被误解为其他东西,(c) 目标接收整个数据文件,没有错误,没有添加或删除任何内容。
- 简单复制:如果我们只是简单地将数据从源盲目地复制到数据包的数据字段中而不进行任何更改,那么形成数据包最容易。
- 唯一起始:数据包起始符号很容易识别,因为它是一个已知的常数字节,在头信息、头信息 CRC、数据有效负载或数据 CRC 中任何地方都不会出现。
- 8 位:只使用 8 位字节。
一些通信协议会破坏透明度,需要在其他地方增加复杂性——需要更高的网络层来实现变通方法,例如 w:二进制到文本编码,否则会遇到神秘的错误,就像 w:时间无关转义序列 那样。
一些通信协议会打破“8 位”——也就是说,除了 256 个可能的字节之外,它们还有“额外的符号”。一些通信协议只有少数几个额外的非数据符号——例如用作 Hayes 转义序列一部分的“长暂停”;用作 SDI-12 协议一部分的“长断开”;4B5B 编码、8b/10b 编码中的“命令字符”或“控制符号”等。其他系统,例如 9 位协议,[5][6][7][8][9][10][11] 传输 9 位符号。通常数据包的第一个 9 位符号的高位设置为 1,唤醒所有节点;然后每个节点检查数据包的目标地址,所有非目标节点都进入休眠状态。数据包中的其余数据(和 ACK 响应)以 9 位符号传输,高位清零到 0,有效地为 8 位值,休眠节点会忽略这些值。(这类似于 MIDI 消息中所有数据字节实际上都是 7 位值的方式;仅在 MIDI 消息的第一个字节中设置高位)。唉,一些 UART 使得发送和接收这种 9 位字符变得很尴尬,[12][13] 困难或不可能。
一些通信协议会打破“唯一开始”——也就是说,它们允许非唯一的开始数据包符号出现在其他地方——最常见的原因是我们正在发送包含该字节的文件,而“简单复制”会将该字节放入数据有效负载中。当接收器第一次打开,或当电缆拔掉后重新连接,或当噪声破坏了原本应该作为真实开始数据包符号的内容时,接收器会错误地将该数据解释为开始数据包。即使接收器通常会识别出出现问题(校验和失败),一次这样的噪声故障也可能导致许多数据包丢失,因为接收器在(错误地)将有效负载中的该数据字节解释为开始数据包,以及(错误地)将真实的开始数据包符号解释为有效负载数据之间来回切换。更糟糕的是,这些常见问题可能会导致接收器丢失对字符开始和结束位置的跟踪。早期的协议设计者认为,一旦同步丢失,就必须有一个唯一的开始数据包字符序列来重新获得同步。[14] 之后的协议设计者设计了一些协议,例如基于 CRC 的帧,[15] 不仅打破了“唯一开始”——允许数据有效负载包含与开始数据包相同的字节序列,支持简单复制透明性——它们甚至不需要固定的不变的开始数据包字符序列。
为了保留“唯一开始”功能,许多通信协议会打破“简单复制”。这需要一些额外的软件,并且每个数据包需要比简单复制数据更多的时间——这在现代处理器中通常可以忽略不计。这种笨拙之处在于(a)确保整个过程——发射机将原始数据的块编码/转义为数据包有效负载,该有效负载必须不包含开始数据包字节,以及接收器将数据包有效负载解码/解转义为原始数据的块——对所有可能的原始数据字节序列都是完全透明的,即使这些字节包含一个或多个开始数据包字节,并且(b)由于编码/转义的有效负载数据不可避免地比原始数据需要更多字节,我们必须确保我们即使在最坏的情况下也不溢出任何缓冲区,并且(c)与“简单复制”不同,在“简单复制”中,有效负载数据位的恒定比特率会导致原始数据位的相同恒定吞吐量,我们必须确保系统被设计为处理有效负载数据比特率或原始数据比特吞吐量或两者的变化。通过使用一致开销字节填充(COBS),[16] 可以减少一些这种笨拙之处,而不是可变开销字节填充技术,例如 SLIP 使用的技术。
计算 CRC 并将其附加到数据包,*在*用 COBS 对原始数据和 CRC 进行编码之前。 [17]
前导码
[edit | edit source]前导码的两种流行方法是
- 第一个发射机发送足够的前导码位,以便此跳跃的接收器锁定。然后它发送数据包。该接收器一旦知道它需要转发数据包到另一个跳跃,就会在下一个跳跃上发送一个新的完整大小的前导码,后面跟着数据包。好处是,无论数据包跳跃多少次,相对较短的固定长度前导码就足够了。
- 第一个发射机发送一个长得多的前导码,远远超出此跳跃的接收器锁定所需的长度。然后它发送数据包。该接收器,一旦检测到前导码,就会立即将每个传入的位从另一个端口发送出去,直到到达数据包的末尾。好处是中继节点可以非常简单,因为它们不需要存储任何数据。前导码消耗 (w:5-4-3 规则#前导码消耗) 会使前导码在每个跳跃后越来越短——丢失太多位,最终没有足够的前导码位来锁定,整个数据包都会丢失。
自动波特率检测
[edit | edit source]
进一步阅读
[edit | edit source]- ↑ Andy McFadden。 "文件格式设计"
- ↑ 维基百科:基本流
- ↑ Gabriel Bouvigne。 "MPEG 音频层 I/II/III 帧头"
- ↑ Predrag Supurovic。 "MPEG 音频帧头"
- ↑ uLan:9 位面向消息的通信协议,通过 RS-485 链接传输。
- ↑ Pavel Pisa。 "uLan RS-485 通信驱动程序" "9 位面向消息的通信协议,通过 RS-485 链接传输。"
- ↑ Peter Gasparik。 "9 位数据传输格式"
- ↑ Stephen Byron Cooper。 "9 位串行协议".
- ↑ "使用 PC 的 UART 与 9 位协议"。1998 年。
- ↑ 维基百科:多点总线 (MDB) 是一种在许多自动售货机中使用的 9 位协议。
- ↑ ParitySwitch_9BitProtocols:操纵奇偶校验以模拟 9 位协议
- ↑ "使用 PC 的 UART 与 9 位协议"。电子设计。1998 年 12 月。
- ↑ Thomas Lochmatter。 "Linux 和 MARK/SPACE 奇偶校验"。2010 年。
- ↑ J. Robinson。 RFC 935。 "可靠的链路层协议"。1985 年。引用:"一旦检测到报头错误,计数字段必须假定为无效,因此必须有一个唯一的字符序列来引入下一个报头,以便接收器可以重新与发送器同步。"
- ↑ 维基百科:基于 CRC 的帧
- ↑ "一致开销字节填充" 作者 Stuart Cheshire 和 Mary Baker,1999 年。
- ↑ Jason Sachs。 "救命,我的串行数据被帧化了:如何在只有流的情况下处理数据包"。2011 年。
- 光学和无线接收器通常需要至少一定长度的前导码才能同步位时钟。有关计算前导码需要多长(多少次转换)的详细信息,请参阅 时钟和数据恢复/CDR 结构和类型/基于一阶 PLL 的 CDR。
- http://intcomm.wiki.taoriver.net/moin.cgi/ProtocolMadness
- UDP
- 互联网技术/协议 包括 TCP/IP 和 HTTP
- ATM
- VSCP - 非常简单的控制协议 http://www.vscp.org/ "该协议是免费的"
- Radia Perlman 著的“协议设计民间传说”。2001 年 1 月 15 日。 http://www.awprofessional.com/articles/article.asp?p=20482
- “一起玩耍的设备,一起工作:UPnP 定义了通用协议和流程,以保证网络设备、家用电器和无线设备之间的互操作性。” 作者:Edward F Steinfeld,EDN,2001 年 9 月 13 日 http://www.reed-electronics.com/ednmag/index.asp?layout=article&articleid=CA154802&spacedesc=readersChoice&rid=0&rme=0&cfd=1
- CAN 总线 http://computer-solutions.co.uk/ http://computer-solutions.co.uk/gendev/can-module.htm
- “CMX-MicroNet 是第一个允许 TCP/IP
- 以及其他协议在小型处理器上原生运行的系统
- ... [包括] AVR、PIC 18、M16C。”
- “byteflight 是一种用于汽车应用的高速数据总线协议” http://byteflight.com/
- Nagle 规则 ... Nagle 算法。“Nagle 规则是一种启发式方法,用于避免发送特别小的 IP 数据包,也称为微型报文。微型报文通常由发送单个按键的交互式网络工具创建,例如 telnet 或 rsh。微型报文在低带宽链路(如 SLIP)上可能会特别浪费。Nagle 算法试图通过在某些情况下短暂地阻止 TCP 数据的传输来避免它们。” -- http://www.tldp.org/LDP/nag/node45.html
- SLIMP3 客户端协议
- Beej 的网络编程指南使用 Internet 套接字 作者:Brian “Beej” Hall,2005 年 11 月 5 日
- “使用 Z86E08 的 RF 链路” 描述了另一个“简单”的数据包协议 ... 还提到了在数据包的其余部分之前训练 RF 接收器的序言。
- 算法实现/校验和
- ... 其他数据包协议 ? ...
- 通信系统/分组数据系统
- 通信网络