可靠的全双工串行通信

时间:2014-02-14 11:07:48

标签: serial-port

我正在设计一种设备,它将加密从PC发送的长(假设无限)数据流并将其发回。我打算在运行全双工的设备上使用单个串行端口进行硬件握手并“阻塞”数据,在每个块之后发送CRC值。该器件仅缓冲有限数量的块 - 理想情况下,只有一个缓冲区累加正在接收的块,一个缓冲区保持当前正在发送的块,在每个块边界切换它们并使用硬件握手来保持同步。

我正在考虑的问题是当出现损坏并且接收器计算的CRC值(可能是PC或设备)与发送的CRC值之间存在不匹配时会发生什么。如果接收器检测到错误,它会在其传输线上设置中断条件 - 因为虽然TX和RX正在执行我们所能做的所有事情,但我们会进入恢复序列。

在数据从发送方消失之前检测到错误条件时,恢复很容易,但特别是在接收到的PC上可能存在大量缓冲区空间,并且当PC赶上并检测到数据损坏时可能已从设备中消失,我们不能简单地重新传输。很难“倒回”密码生成,因此重新发送源数据并尝试在中间拾取内容很困难 - 实际上源数据可能无法重新发送,具体取决于它最终来自何处。

我考虑让每一方发送其“最后一帧成功接收”计数器及其最后一帧发送的CRC值,如果在输出端有太多未经证实的数据等待,则设备会丢弃RTS,但这会导致死锁 - 设备永远不会得到PC的接收线程已经赶上的确认。

我还考虑让PC发送一个块然后再发送另一个块,直到第一个块被确认处理并收到回来,但这实际上是半双工或块同步操作,系统运行速度比它快可以做。折衷方案是在设备中有多个缓冲区,PC可以知道有多少缓冲区,并根据它认为设备正在做什么来限制它自己的输出,但在PC端需要那种程度的“智能”不雅和hacky。

串行通信是非常古老的技术。当然有一个很好的方法吗?

1 个答案:

答案 0 :(得分:4)

设计可靠的协议并不容易。关于你到目前为止所谈到的内容的一些注释:

  • 仅使用RTS执行其设计要做的操作,避免接收缓冲区溢出。它不适合做更多。
  • 强烈考虑有多个未确认的框架。只有当连接遭受高延迟时才很重要,这对串口来说不是问题。
  • 通过分层实现全双工操作,使用OSI模型作为指导。
  • 确保将协议的输入和输出视为纯字节流。成帧只是协议实现的细节,实际帧大小无关紧要。如果应用程序通过使用消息发出信号,那么应该在协议的顶层上实现。否则是适当分层的自动结果。
  • 请记住,帧不仅可以传输数据,还可以包含接收帧的ACK。换句话说,如果没有任何要传回的内容,您只需要一个单独的ACK帧。

并且避免重新发明轮子,这是以前做过的。我可以推荐RATP,RFC916的主题。广泛忽略btw所以你不太可能找到你可以复制的代码。我实施了它并取得了很大的成功。它只有一个我所知道的缺陷,它对接收缓冲区中存在的多个连接尝试没有弹性。打开端口时故意清除缓冲区很重要。