2

我正在用 Python 开发一个应用程序,它通过 RS-485 两线半双工与设备通信。我有足够的应用程序工作,可以执行一些性能测试。我正在使用带有 USB 到 485 转换器的笔记本电脑。通讯设置为 9600,N,8,1。

对于我的速度测试,我发送了一条总长度为 10 个字节的消息,包括校验字节。然后我等待 13 个字节的回复。我在回复进来时对其进行解码。当回复完成时。然后我发送下一条消息。我尽可能快地重复这 100 次。这需要 2.895 秒。

由此我计算出我正在发送/接收 23 字节 * 100 次迭代 / 2.895 秒 = 794 字节/秒。

如果我理解正确的话,9600 N-8-1 的串口通信有 1 个起始位、8 个数据位和 1 个停止位。这意味着它有 2 位开销。所以实际的理论传输速率为(9600 位/秒)*(8 数据位/10 传输位)*(1 字节/8 位)=960 字节/秒。

我的程序在可能的 960 字节/秒 = 82.7% 中以 794 字节/秒的组合速率发送/接收。

我应该能够达到接近 100% 的 960 字节/秒吗?还是通常没有使用这么多带宽?

4

1 回答 1

4

当交流的方向颠倒时,你会放弃一些时间。因此,在一侧接收到最后一个停止位与将第一个响应字节加载到 UART 发送器并开始驱动第一个起始位之间存在一些“死区时间”。

我计算这个死区时间是 5 毫秒(几乎 5 位时间,即半字节计数帧开销),每次双向运行,或 2.895 总秒数中的 0.495 秒。这还不错,但可能会好一点。但是,如果不编写自己的 UART 驱动程序,我不确定您是否会得到很大的改进。

(当然,这一切都假设两台计算机使用的时钟都是精确的。这并不总是正确的,因为 8N1 的 UART 可以容忍每端之间高达 2% 的时钟差异。)

在嵌入式领域,如果我们想以绝对最小的带宽损失做到这一点,我们会将驱动程序编写为标准的双向全双工驱动程序,并通过某种方式知道何时切换方向(例如在数据包边界上)。然后,该驱动程序将仅将字节推向正确的方向,而使其他队列未使用。

在用户(应用程序)级别,我们必须确保这些队列永远不会被饿死。这意味着,在您的示例中,13 字节的响应数据包需要在完全接收到 10 字节的传入数据包之前准备好。另一端也需要这样做。

对于较大的机器,通常的做法是在每个方向上“合并”几个数据包并连续传输它们,以最大限度地减少您必须改变方向的次数。但是,这会增加延迟,并且需要更多内存,这对于只有几 kB RAM 的小型微控制器可能是个问题。

恕我直言,鉴于您的小数据包、频繁的方向反转以及缺乏驱动程序级别的优化,带宽看起来是正确的。

于 2013-12-07T05:18:15.193 回答