什么是串口传输需要发送的内容?

8
很抱歉如果我的问题不够清晰,我无法正确表达它以找到其他遇到同样问题的人。主要问题是,一旦两个设备之间建立了串行连接,如何使用该连接实现双向通信?
举个例子,假设你有一个嵌入式设备作为温度传感器,使用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进行解析。对于计算机端而言,它将非常实用,因为它可以使用高级语言(如Java)来读取JSON数据的库。
分组式API:
这是我们接受并且我现在有些后悔的解决方案。它涉及为我们发送的每个数据发送结构化的字节包约定。包结构如下所示:[0xFF][0xFF][ID][CMD][D0][D1][D2][D3][D4][D5][D6][D7][0xEE][0xEE][0xEE]
使用这种结构,我们发送头和尾(0xFF和0xEE)来验证数据包的完整性,一个ID用于发送顺序数据包(用于传输数据数组),一个数据数组,我们可以使用它来打包长整型,浮点型,整型等,以及一个命令字节(CMD),设备可以使用它来确定如何解析数据负载(D0-D7)。
那么我想问,串行端口通信最受欢迎的方式是什么?还有其他我没有考虑到的方式吗?最近我一直在做Web开发,JSON似乎是一个不错的抽象传输系统,但它也有其局限性,因为您必须进行更多的字符串解析,这在固件方面有些复杂。

除了它是专有的之外,你使用的方法有什么问题?你所说的“首选”是什么意思?在嵌入式设备上,有一些小型可靠的JSON解析器可以使用:http://zserge.bitbucket.org/jsmn.html - Robert Harvey
大多数JSON都是在网络上使用的,其中JSON消息的文本被包装在数据包中,并进行校验以确保它到达您发送的位置。原始串行字节不能保证正确传输。(通常失败是一个或多个位序列。也许有一些整个字节。)您需要做一些事情来验证消息的完整性并验证您发送的内容是否真正到达了那里。您使用的工具应该能够实现这一点。 - Lee Meador
首先,它将使用限制在256个命令类型。为了解决这个问题,我们打破了单个数据包发送数据和命令的惯例。现在,我们发送一个数据包,其中的数据设置我们要设置的参数ID,并发送一个单独的数据包,将该参数设置为要设置的值。从某种意义上说,它已经将状态实现到我们的传递系统中,固件必须记住RAM中的ID,直到获得数据以将该参数设置为所需值。我们使用2个数据包,而不是1个,使失败更有可能发生。通过“首选”我指的是肯定有其他人有更好的方法来发送和解析结构化数据。 - JBausmer
1
JSON-RPC 是一种处理发送和接收确认的常见方法,您觉得如何? - Shawn Shaw
2个回答

5
这里最大的问题是缺乏标准。几乎每个人都会为约束设备或类似UART/串行线的低级传输实现自己的协议。但随着物联网趋势的增长,这种情况有望得到改变。
请查看SLIP和SLIPMUX,以通过串行线发送面向数据包的协议。
无论您发送JSON、XML还是其他任何内容,您很可能需要一些停止标志来终止消息。通常使用\n与ASCII编码的内容结合使用,但这不适用于二进制编码的机器对机器通信。
SlipMux向后兼容SLIP(用于IPv4和IPv6数据包),但也支持新的消息类型,如CoAP和诊断(人类可读)消息。您可以简单地实现自己的数据包类型,比如“JSON”或“XML”消息。
作为协议,我推荐在SlipMux中与CoAP结合使用。CoAP与HTTP非常相似,但更轻量级,因此对大多数开发人员来说更容易处理。
CoAP: https://www.rfc-editor.org/rfc/rfc7252 Slip: https://www.rfc-editor.org/rfc/rfc1055 SlipMux: https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-00

3
二进制数据包格式因其明显的简单性和高效性而具有吸引力。此外,某些通信链路已经将数据作为固定大小的数据包发送(USB、TCP/IP、文件系统等),但如果我必须再次选择,我不会选择这种方式,因为存在以下缺点:
- 不可读(除非您想混淆事情并保护您的协议 :-) ) - 计算机体系结构相关:考虑字节序问题 - 工具链依赖性:例如,编译器X如何打包数据结构与编译器Y? - 链接依赖性:如果链接更改,如果协议数据包大小与新链接数据包大小之间存在奇怪的匹配?
现在,我的选择是JSON:ASCII数据传输比二进制传输效率低,但其便利性和可移植性可以抵消这一点,除非应用程序具有严重的带宽限制。我个人为Arduino Uno板编写了一个JSON解析器,它在不到2KB的数据RAM中工作,包括系统堆栈。好吧,它可能会在嵌套的JSON传输上发生故障,但足以从Twitter推文数据包中剥离关键元素,并证明它可以在小型系统上工作。
Yves McDonald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接