我有一个嵌入式系统通过串口进行通信。现在的命令结构设计是交互式操作的:它显示提示符,接收几个命令,并以人类可读的形式显示结果。
我正在考虑将其更改为更适合机器使用的格式,这样我就可以通过MATLAB GUI与其交互而不会遇到太多麻烦(现在它在交互式提示和变化的消息长度等方面有问题)。
因此,请问是否有文件或标准描述如何为您的嵌入式系统设计良好的串行命令协议?
我有一个嵌入式系统通过串口进行通信。现在的命令结构设计是交互式操作的:它显示提示符,接收几个命令,并以人类可读的形式显示结果。
我正在考虑将其更改为更适合机器使用的格式,这样我就可以通过MATLAB GUI与其交互而不会遇到太多麻烦(现在它在交互式提示和变化的消息长度等方面有问题)。
因此,请问是否有文件或标准描述如何为您的嵌入式系统设计良好的串行命令协议?
我在使用RS232控制媒体和显示设备时有一些偏好(和烦恼)。根据你的硬件,其中一些可能不适用:
我认为让协议更加易于自动化是个好主意。如果需要交互式界面(命令行或其他),请单独构建,并使用自动化协议。我不会过多考虑使其对人类可读,但这由你决定。
始终返回响应,即使(特别是)收到无效命令。可以使用简单的$06表示ACK和$15表示NAK,或者如果想要稍微更容易理解,则可以详细说明。
如果可以设置任何值,请确保有某种方法查询相同的值。如果有很多值,则可能需要一段时间才能查询它们所有。考虑只返回几个元查询中的一个,以一次返回多个值。
如果有一些不能设置但很重要的信息(型号、序列号、版本、版权等),请确保可以查询它们而不仅仅在启动或重置时显示一次。
永远不要对有效命令响应错误。你本以为这一点很明显…
说起明显,记录硬件支持的串行设置。特别是如果它将被除你以外的任何人使用,而你不希望他们花30分钟来确定他们无法与设备通信是因为串口、连接、电缆还是软件问题。并不是我很生气…
使用绝对命令而不是切换值。例如,单独发送打开和关闭电源的命令,而不是发送相同的命令并切换电源的开关。
响应应包括它们响应的命令信息。这样,任何程序都不需要记住上次请求的内容以处理响应(参见下面的额外学分选项)。
如果您的设备支持待机模式(关闭,但不是真正的关闭),请确保在该状态下查询仍然有效。
根据您对数据完整性的担忧程度:
将消息包装在信封中。标题可以包括起始字符、消息长度和结束字符。以防您收到部分或格式错误的消息。例如,起始字符可能是$02,结束字符可能是$03。
如果您非常担心消息的完整性,请包括一个校验和。不过这可能会有点麻烦。
额外加分项:
希望这可以帮到您。
更新:
我忘记了一些重要的事情。在您真正使用它之前,特别是在将其提供给他人之前,请在一些琐碎的东西上试用它,以确保它按照您的预期工作,并且(更重要的是)确保您没有遗漏任何东西。如果在进行更大的项目时发现问题,修复它将需要更多的时间和精力。
无论您是在设计命令协议、Web服务、数据库模式还是类等,这都是一个不错的经验法则。
这里是Eli Benderski关于串行协议数据帧的优秀文章。无论你选择哪种数据包格式,请务必使用转义字符,这样可以使实际数据中包含此类字符并且在数据包出现错误时很容易重新同步。
在数据包中返回数字类型时,请尽量使所有内容格式相同。不要有一些数字是单数,而其他数字是双数。而且不要任意制定!
在ICD中为数据包提供示例。猜测字节顺序甚至位顺序(MSByte先还是后?什么是第一个和最后一个?)非常令人沮丧。提供一个显示数据包与时间的图表(即,0x02最早发送,然后是地址字节,然后是消息ID等)。
如有可能,请不要在数据格式之间切换。我曾经在使用“ASCII编码数字”的系统中工作,在某些消息中您必须剥离字节前面的“3”,然后将它们拼在一起以得到真实数字。(通常情况下,当您需要避免字节序列时,例如0x02、0x04等时,才会使用ASCII编码。 编码的数字将为0x30、0x32、0x30、0x34。如果可能,请使用长度字段来避免这种情况,或者至少始终这样做!)
一定要记录波特率、奇偶校验等信息。如果您正在使用RS-485,请记录总线模式(2线?4线?)或任何将出现在您打算使用该设置的机器上的设置。如有必要,请提供截图。
此接口可能非常有用于调试。我曾经使用过某些具有调试功能的系统,例如:
程序员制作了一个“已记录参数”列表(内部变量)。您会告诉系统您要报告哪些参数(最多8个),然后当您查询已记录的参数时,它将以一个数据包返回它们。我喜欢这个,但是根据系统的复杂性,您可能无法在运行时指定它们(或者您可以做一些简单的事情,向系统发送一个掩码,以选择您想要返回的参数)。
“破坏”行为的数据包,并允许测试系统的部分独立地进行测试(即,在D/A上输出这个电压,在DIO端口上刺激这个字节等)
祝你好运!
<slip packet start>
message
message crc
<slip packet start>
FTP是一个可以在交互和自动化中都良好运作的协议示例。其中一个关键点是响应以指示自动化客户端是否需要注意的代码开头。POP3也是如此。
这些协议的一大好处是,在开发/调试时,您可以使用常规终端驱动通信,或者使用常规shell脚本/批处理文件/等等脚本化通信。
然而,它们所不能提供的是可靠性——这由通信堆栈的更低层提供。在大多数嵌入式通信路径中,应该考虑这一点。
你是否看过Modbus(http://www.modbus.org/)?这是一种相当简单的协议,每个消息都包含一个校验和。即使那些不需要“返回值”的命令也会发送响应,因此您可以知道您的命令是否正确接收。选择Modbus后唯一的选择是要将数据存储在哪个寄存器地址以及用户定义函数的格式(MODBUS协议允许)。
以Firmata作为一个示例协议。