【问题标题】:Reliable full-duplex serial comms可靠的全双工串行通讯
【发布时间】:2014-02-14 11:07:47
【问题描述】:

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

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

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

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

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

串行通信是相当古老的技术。肯定有这样做的好方法吗?

【问题讨论】:

    标签: serial-port


    【解决方案1】:

    设计一个可靠的协议并不是那么容易。到目前为止您所谈论的内容的一些注释:

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

    并且避免重新发明轮子,这已经完成了。我可以推荐RATP,RFC916的主题。顺便说一句,被广泛忽略,因此您不太可能找到可以复制的代码。我已经实施了它并取得了很好的成功。据我所知,它只有一个缺陷,它对接收缓冲区中存在的多次连接尝试没有弹性。打开端口时有意清除缓冲区很重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-24
      • 2012-12-06
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      相关资源
      最近更新 更多