可靠的全双工串行通信

3
我正在设计一台设备,它将加密从PC发送的长(假设是无限)数据流并将其发送回来。我计划在设备上使用单个串行端口,在全双工模式下运行,并“阻塞”数据,每个块后发送CRC值。该设备仅缓冲有限数量的块-理想情况下,只需一个缓冲区累积接收到的块和一个缓冲区持有目前正在发送的块,在每个块边界进行切换,并使用硬件握手来保持同步。
我考虑的问题是,当存在损坏并且接收方计算出的CRC值与发送的值不匹配时会发生什么。如果接收器检测到错误,则在其传输线上设置中断条件-因为尽管TX和RX正在执行不同的操作,但那就是我们可以做的全部-然后我们进入恢复序列。
当在数据从发送方消失之前检测到错误条件时,恢复很容易,但尤其是在PC接收方,可能有大量的缓冲空间,当PC赶上并检测到损坏时,数据可能已经从设备中消失,我们不能简单地重传。很难“倒带”密码生成,因此重新发送源数据并尝试在中途连接可能很困难-实际上,源数据可能无法重新发送,具体取决于它最终来自哪里。
我考虑让每一方在其最后一帧成功接收的计数器以及其最后一帧发送CRC值的同时发送,并且如果输出中有太多未经确认的数据等待,则让设备降低RTS,但是那样会死锁-设备永远无法获得PC接收线程已赶上的确认。
我还考虑了让PC发送一个块,然后不再发送另一个块,直到第一个块被确认处理并返回,但这实际上将转向半双工或块同步操作,而该系统运行速度比可以做的慢。一种折衷的方法是在设备中使用多个缓冲区,让PC知道有多少个缓冲区,并根据它认为设备正在执行的操作来控制其自己的输出,但需要在PC端具有那种程度的“智能”似乎不太优雅和精湛。
串口通信技术相当古老。肯定有更好的方法来做到这一点吧?
1个回答

4
设计一个可靠的协议并不容易。以下是一些关于你所谈论的内容的注意事项:
- 只使用 RTS 来执行其设计用途,避免接收缓冲区溢出。它不能做更多的事情。 - 强烈考虑不要有多个未确认的帧。只有在连接受到高延迟的影响时才重要,这在串行端口上不是问题。 - 通过分层实现全双工操作,使用 OSI 模型作为指南。 - 确保将协议的输入和输出视为纯字节流。帧格式仅是协议实现的细节,实际帧大小并不重要。如果应用程序使用消息进行信号传递,则应在协议之上实现该功能。否则,这是正确分层的自动结果。 - 记住,一帧可以做的不仅仅是传输数据,还可以包括对接收帧的 ACK。换句话说,只有在没有任何东西需要传输回去时才需要单独的 ACK 帧。
避免重复造轮子,这已经做过了。我可以推荐RATP,RFC916的主题。它被广泛忽视,所以你不太可能找到可以复制的代码。我已经实现了它并取得了良好的成果。我只知道一个缺陷,就是它不能抵御接收缓冲区中存在的多个连接尝试。在打开端口时有意地清除缓冲区非常重要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接