python中解析缓冲区字符串的最佳方法

2024-10-01 13:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究一个通过Uart发送命令的嵌入式系统。 通用异步收发器工作在115200波特

在PC端,我想读取这些命令,解析它们并执行相关操作。

我选择python作为构建脚本的语言。

这是从嵌入式系统接收到的典型命令:

S;SEND;40;{"ID":"asg01","T":1,"P":{"T":180}};E

每条消息以S开头,以E结尾。 与消息相关的命令为“SEND”,有效负载长度为40。

我的想法是读取来自UART的字节并:

  • 检查消息是否以S开头
  • 检查消息是否以E结尾
  • 如果上述假设为真,则拆分消息以找到命令和有效负载。在

解析来自异步uart的所有字节的最佳方法是什么?

我关心的是由于错误(或缓慢)解析而导致的消息丢失。

谢谢你的帮助!

比尔, 费德里科


Tags: 命令脚本send语言id消息字节系统
2条回答

这种格式几乎可以解析为csv,但不完全可以,因为第四个字段是JSON,您可能无法保证JSON不包含任何带有嵌入分号的字符串。所以,我想您可能只想使用字符串(或者更确切地说,字节)操作函数:

def parsemsg(buf):
    s, cmd, length, rest = buf.split(b';', 3)
    j, _, e = rest.rpartition(b';')
    if s != b'S' or e != b'E':
        raise ValueError('must start with S and end with E')
    return cmd.decode('utf-8'), int(length), json.loads(j)

然后:

^{pr2}$

实际的分号解析部分需要我的笔记本电脑上的602ns,decode和{}将其提高到902ns。另一方面,json.loads需要10个单位。因此,如果您担心性能,那么JSON部分实际上是唯一重要的部分(尝试一下我安装的第三方JSON libs,最快的还是8.1us,这一点也不好)。你还不如把其他一切都保持简单和健壮。在

另外,考虑到你正在以115000波特的速度阅读这篇文章,你不可能以6毫秒的速度得到这些消息,所以花11个小时来解析它们根本就不是一个问题。在

在我的日常工作中,我编写了一个嵌入式系统和一台PC机通过USB电缆进行通信的软件,使用的是115200波特的UART协议。在

我看到您用PySerial标记了您的帖子,因此您已经了解了Python最流行的串行端口通信包。我要补充的是,如果您使用的是PyQt,那么这个包中还包括一个串行模块。在

115200波特对于一台现代台式电脑来说并不快,我怀疑你在电脑端做的任何解析都会跟不上。我使用PyQt实时解析数据流并绘制数据图。在

在我的工作中,我注意到嵌入式系统和PC机之间通过UART进行通信时,有些数据偶尔会被损坏。一个字节可以被乱码、重复或删除。此外,即使没有添加或删除字节,您也可以偶尔在只有部分数据包在缓冲区时执行读取,并且读取将提前终止。如果您使用40字节的固定读取长度,并且相信每次读取都将与上面所示的数据包完全一致,则通常会出错。在

为了解决这类问题,我用Python编写了一个FIFO类,它在FIFO的头部消耗串行端口数据,在尾部生成有效的数据包,并丢弃无效的数据。我的FIFO保存的字节是我的数据包的3倍,所以如果我使用特定的序列来寻找数据包边界,我有很多路标。在

还有一些建议:使用python3,如果你有选择的话,它会更干净。使用bytes和bytearray对象。不要使用str,因为您会发现自己在Unicode和ASCII之间来回转换。在

相关问题 更多 >