Ben*_*son 9 embedded checksum serial-port driver
我正在研究一种通过串行端口控制8位MCU的现有驱动程序.MCU有许多不同类型的固件,但它们都有共同的方法来尝试确保链路完整性.这个方法不是很强大,我正在寻找有关驱动程序如何修改其行为以充分利用它的想法.
命令是带有行号和校验和的gcode:
N3 T0*57
N4 G92 E0*67
N5 G28*22
N6 G1 F1500.0*82
N7 G1 X2.0 Y2.0 F3000.0*85
N8 G1 X3.0 Y3.0*33
Run Code Online (Sandbox Code Playgroud)
行号必须是顺序的(但可以重置M110).如果校验和不匹配或行号是失序的固件将回复Resend: nnn这里nnn是最后的成功N加1."校验"是极其原始:
// Calc checksum.
byte checksum = 0;
byte count = 0;
while(instruction[count] != '*')
checksum = checksum^instruction[count++];
Run Code Online (Sandbox Code Playgroud)
主要问题是主要错误机制是由于中断被保持关闭导致1字节MCU FIFO溢出而丢弃的字节.实际的串行总线在FTDI(或类似)USB串行桥和MCU之间只有几厘米,因此不太可能出现误码.我从来没有在固件的回复中发现有点错误.
正如您所看到的,上面的算法会检测到一个丢弃的字节,但如果丢弃了两个相同的字节(任何地方!),结果仍然匹配.因此F3000.0(进给率3000mm/min)可以转化为F30.0并仍然匹配.此外,字符集非常小,因此永远不会涉及某些位.
驱动程序可以做些什么来使给定的行更健壮吗?
X1 Y1相同Y1 X1)F2999.9而不是F3000)N给定行的特定行G1 X2变为G1 X1 G1 X2假定X = 0最初)T0,对于大多数命令来说是无意义的,如果你发送F3000一次它将来暗示,所以可以选择性地发送它)如果我认为固件会丢弃组中的字节,那么最重要的可能是避免背靠背重复,例如00哪些(如果放在一起)是不可见的.
您可以尝试的一件事是在主机上配置UART以发送2个停止位而不是1(这是您当前可能正在使用的).除了在字符之间存在额外的空闲比特时间之外,MCU接收器将不会注意到任何内容.在下一个字符移入之前,将字符从接收寄存器中取出的时间大约多10%.
通常,UART不会在接收数据上寻找超过1个停止位,即使UART配置为2个停止位(没有理由在接收时强制执行额外的停止位),因此MCU仍将发送只有一个停止位不会导致从设备接收响应时出现任何问题.
如果你处于高数据速率,这不会增加太多时间,所以它可能无济于事(但这取决于超出的根本原因是什么).如果我的加密是正确的,那么如果你以38400 bps的速度运行链接,MCU可以再用25微秒来避免超限.
这是一个很长的镜头,但这是一个廉价的改变,除了主机端的串口配置之外,不需要修改.
我们可能并不熟悉 G 代码,链接对于特定领域的技术总是有帮助的。
我想说,简单的校验和可能足够适合数据长度、格式和处理器性能。如果您已经丢弃了字符,那么您几乎不想通过 CRC 添加更多 CPU 负载,是吗?
在这个协议中你有多重防线。数据必须格式良好、按顺序排列,并通过校验和,它的有效字符集似乎也相当有限。因此,一起检查语法、序列和校验和可能会非常稳健。此外,您还可以检查参数值是否在范围内,当然,如果您选择使用,您的 UART 将具有基本的奇偶校验检查。
通过测试 UART 的溢出标志可以更好地解决 UART Rx 寄存器溢出的问题。UART 总是具有硬件溢出检测,并在溢出错误时生成中断。如果您的串行输入是中断驱动的,那么您可能没有启用和处理溢出,或者您可能忽略它并将其视为正常接收中断。如果没有出现溢出,则问题出在 FTDI 设备上,并且数据丢失发生在它到达 UART 之前。下面的最后两段讨论了该问题的可能解决方案。
该链接以什么波特率运行?在大多数情况下,如果您在典型的 UART 数据速率上丢失字符,那么该实现就有缺陷。您可能不恰当地关闭中断太长时间,在中断级别做了太多工作,或者选择了不适当的中断优先级。您需要解决根本原因,而不是尝试解决协议级别的基本实现问题;这是为了应对嘈杂的数据链路,而不是糟糕的软件。
另一个可能的问题是FTDI设备。我见过多个 FTDI 驱动程序发生冲突并导致数据丢失的问题。这种情况的解决方案是使用 FTDI 的 FTClean 实用程序删除驱动程序,然后重新安装最新的驱动程序。尽管您可以通过 Google 搜索间接获得 FTClean,但他们的网站上似乎没有 FTClean。FTDI 的网站确实有一个不同的删除工具,我猜它已经取代了 FTClean。您在使用真正的串口时是否遇到同样的问题?我还发现使用 Prolific 设备和驱动程序的 USB 串行设备特别容易丢失数据,即使在中等数据速度下也是如此。
最后,我发现使用各种 USB 串行设备的许多数据丢失问题可以通过“节奏”输出来解决。有些设备的内部缓冲区相当小。您可能已经注意到,在大约 128 个字符之后或无论 USB 设备的内部缓冲区大小如何,字符丢失开始发生。在数据流中插入短延迟(例如 10 毫秒)可以解决此问题。在这种情况下,您可以简单地在每行末尾执行此操作。另一种“节奏”方法是轮询 PC 应用程序中的传输缓冲区,并等到它为空后再添加更多数据,然后仅添加小块数据,在您的情况下可能是单行。我发现这通常可以解决数据丢失问题,并且数据传输性能没有明显的损失。