我正在开发一个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字节/秒的组合速率进行发送/接收。
我是否能够达到960字节/秒的接近100%。或者通常没有利用这么多的带宽?
答案 0 :(得分:4)
当沟通的方向发生逆转时,你会放弃一些时间。因此,当一端接收到最后一个停止位和将第一个响应字节装入UART发送器并开始驱动第一个起始位之间存在一些“死区时间”。
我正在计算每个双向运行的这个死区时间是5 ms(几乎是5位时间,即计算帧开销的半个字节),或者是2.895总秒数的0.495秒。这不错,但可能会好一些。但是,如果不编写自己的UART驱动程序,我不确定会有多大改进。
(当然,这一切都假设计算机正在使用的时钟都是晶振精确的。这并非总是如此,因为8N1处的UART可以容忍每端之间最多约2%的时钟差。)
在嵌入式领域,如果我们想要以绝对最小带宽损耗来实现这一点,我们将驱动程序编写为标准的双向全双工驱动程序,以某种方式知道何时切换方向(例如,在数据包边界上) )。然后,此驱动程序只会按正确的方向推送字节,而另一个队列则不使用。
在用户(应用程序)级别,我们必须确保这些队列永远不会饿死。这意味着,在您的示例中,13字节响应数据包需要准备好在完全接收到10字节传入数据包之前。另一端需要做同样的事情。
对于较大的机器,通常的做法是在每个方向上“合并”几个数据包并连续传输它们,以便最小化您必须改变方向的次数。但这会增加延迟,并且需要更多内存,这对于只有几兆内存的小型微控制器来说可能是一个问题。
恕我直言,鉴于您的小数据包,频繁的方向反转以及缺乏驱动程序级优化,带宽看起来是正确的。