【发布时间】:2013-09-09 18:24:02
【问题描述】:
如果这是一个非常模糊的问题,我很抱歉,但我似乎无法正确地制定它来找到其他有此问题的人。主要问题是,一旦你在两个设备之间建立了串行连接,你如何使用这个连接来实现双向通信?
一个例子可能会有所帮助。假设你有一个温度传感器作为嵌入式设备,它使用一个用 C 语言编写的微控制器和固件。你有一个从传感器到计算机的串行端口连接,以及计算机上的一些软件来与它交互,比如 C++ 应用程序。我了解如何在两侧设置串行端口并在两个设备之间读取和写入单字节数据。真正的问题是您使用什么约定在两个设备之间进行通信?
假设您的要求如下:
1.) 您需要能够发送命令以从嵌入式设备获取单个温度读数并将其发送到计算机以进行显示。
2.) 您需要发送命令以使传感器开始和停止流式传输温度值。
3.) 您需要一组命令来设置固件中的各个方面,例如流式传输速率、启动时流式传输、闪烁 LED 等。
4.) 您需要某种结构将复杂形式的数据发送到计算机,可能是一组电池电压读数。
实现方法
似乎人们倾向于这样做:
简单字符串 API:
处理第三方传感器时,最常见的似乎是使用简单的基于字符串的 API,这样启动和停止流的命令可能分别是“SS,1\r”和“SS,0\r”。在这种情况下,您必须从串行端口读取,直到获得“\r”字符,然后解析您获得的数据以查看它是否具有命令(逗号左侧)和参数(逗号右侧)。这适用于上述场景 1 到 3,但不会让场景 4 变得非常简单。
JSON 字符串 API:
这与上面的工作方式相同,但不是将参数作为简单值传递,而是传递可以表示复杂数据结构的 JSON 对象。因此,您可以将电池电压数组作为 JSON 数组发送。此方法似乎涵盖了上述所有用例 1-4。但是 JSON 发送字符串,并且使用嵌入式 c 更难解析。它可以为计算机端创造奇迹,它可以使用更高级别的语言,例如具有用于读取 JSON 数据的库的 Java。
数据包样式 API:
这是我们接受的解决方案,我现在有点后悔。它涉及为我们发送的每条数据发送一个结构化的数据包约定。数据包结构如下图。
[0xFF][0xFF][ID][CMD][D0][D1][D2][D3][D4][D5][D6][D7][0xEE][0xEE][0xEE]
通过这个结构,我们发送一个用于验证数据包完整性的页眉和页脚(0xFF 和 0xEE),一个用于发送顺序数据包(用于传输数据数组)的 id,一个我们可以用来打包 long、float、 ints 等,以及一个命令字节 (CMD),设备可以使用它来确定如何解析数据负载 (D0-D7)。
所以我问,通过串行端口进行通信的最首选方式是什么?还有其他我想念的方法吗?最近一直在做很多web开发,看起来JSON是一个很好的抽象传输系统,但是有它的局限性,因为你必须做更多的字符串解析,这在固件方面有点复杂。
【问题讨论】:
-
您使用的方法有什么问题,除了它是专有的吗? “首选”是什么意思?您可以在嵌入式设备上使用小型、可靠的 JSON 解析器:zserge.bitbucket.org/jsmn.html
-
大多数 JSON 在网络上使用,其中 JSON 消息的文本被包装在数据包中并进行校验和验证,以确保它到达您发送它的位置。原始串行字节不能保证正确传输。 (通常故障是序列中的 1 位或更多位。可能是整个字节。)您需要做一些事情来验证消息的完整性并验证您发送的内容是否实际到达那里。你使用的应该这样做。
-
一方面,它将使用限制为 256 种命令类型。为了解决这个问题,我们打破了在单个数据包中发送数据和命令的惯例。我们现在发送一个数据包,该数据包设置我们要设置的参数 ID,以及一个单独的数据包,该数据包发送要设置该参数的值。从某种意义上说,它已经在我们的交付系统中实现了状态,固件必须在 ram 中记住一个 ID,直到它获得要设置该参数的数据。我们在过去使用 1 个数据包的地方使用 2 个数据包,使失败的可能性更大。首选我的意思是肯定有人有更好的方法来发送和解析结构化数据。
-
处理发送和接收确认的 json-rpc 怎么样?也是一种常用的方法。
标签: json serial-port packet