设计前向兼容通信协议的指南?
我正在研究嵌入式设备之间的通信协议。该协议将来肯定需要新的命令和字段。我需要做什么才能确保自己不会陷入困境?
I'm working on a communication protocol between embedded devices. The protocol will definitely need new commands and fields in the future. What do I need to do to make sure I'm not painting myself into a corner?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个广泛开放的问题。以下是一些关于它的随机想法:
生长。
总结一下,留备件。
This is a wide open question. Here are some random thoughts about it:
growth.
In summary, Leave spares.
如果可能的话,让电缆一端的人弄清楚电缆另一端的情况。
理想情况下,人类可以连接一个哑终端并敲击键盘三下(输入问号-回车),然后会返回一条长而详细的消息,描述它是什么类型的机器,它的型号是什么,名称和构建它的组织的电话号码和网站、“官方”协议版本号以及非官方构建时间:
每次机器启动时也发送相同的详细消息。
如果可能的话,尝试设计您的协议,以便具有哑终端的人可以与您的设备进行通信。
HTTP 就是这样一种人类可读的协议,我怀疑这是它流行的原因之一。
人类可读意味着:除其他外,
避免特殊控制字符。利用纯文本的力量。
您可能还想浏览一下嵌入式系统的常用协议列表。
也许其中一个已经满足您的要求了?
是否有任何理由使用比标准 Netstring 格式更难解码的格式?
If at all possible, allow a human at one end of a cable to figure out what is at the other end of the cable.
Ideally, a human could hook up a dumb terminal and hit the keyboard three times (Enter Question-mark Enter), then a long, detailed message would come back describing what kind of machine it is, what is its model number, the name and phone number and web site of the organization that built it, the "official" protocol version number, and the unofficial build time:
Also send the same detailed message every time the machine boots up.
If at all possible, try to design your protocol so that a human being with a dumb terminal can talk to your device.
The HTTP is one such human-readable protocol, and I suspect this is one of the reasons for its popularity.
Human-readable implies, among other things:
Avoid special control characters. Take advantage of the power of plain text.
You might also want to glance over the list of common protocols for embedded systems.
Perhaps one already meets your requirements?
Is there any reason to use something more difficult to decode than the standard Netstring format?
这个问题有点太笼统,无法给出明确的答案。嵌入式系统可能需要在很多方面进行通信,例如:
它需要与多少个同行进行通信?
需要多少数据才能通信?
系统需要有多紧密的同步?
协议的物理介质是什么?带宽限制和错误敏感性考虑因素是什么?
所有这些要求和资源限制肯定会限制系统,然后您可以开始弄清楚协议需要什么。一旦您了解了这些问题,您就可以预测某些需求将来可能会如何变化/扩展。从那里您可以设计协议来适应(或不适应)最坏的用例。
The question is a little too general for a clear answer. There are many aspects an embedded system may need to communicate like;
How many peers will it need to communicate with?
How much data does it need to communicate?
How tightly synchronized do the systems need to be?
What is the physical media for the protocol and what are the bandwidth limitations, and error susceptibility considerations?
All of these requirements and resource limitations will certainly constrain the system and then you can start to figure out what the protocol will need. Once you know these issues you can then project how some the requirements may change/expand in the future. From there you can design the protocol to accommodate(or not) the worst case use cases.
我会使用HDLC。我过去在这方面运气很好。对于点对点串行,只需使用 异步帧 并忘记所有其他控制的东西,因为它可能是矫枉过正的。
此外还使用 HDLC 来对数据包进行成帧。我将数据包格式化如下。这就是使用 802.11 传递选项的方式
每个命令数据包的总大小为 len +2
然后定义命令,如
另一个优点是您可以添加新命令,如果您正确设计解析器以忽略未定义的命令,那么您将有一些向后兼容性。
因此,将所有内容放在一起,数据包将如下所示。
然后,系统将监视串行流中的标志 0x7e,当它出现时,您检查长度以查看它是否 pklen >= 4 且 pklen=len+4 以及 crc 是否有效。请注意,不要仅依赖 crc 来处理小数据包,在检查长度时您也会得到很多误报。如果长度或 crc 不匹配,只需重置长度和 crc 并开始解码新帧。如果匹配,则将数据包复制到新缓冲区并将其传递给命令处理函数。当收到标志时,总是重置长度和 crc。
对于命令处理函数,获取 cmd 和 len,然后使用开关来处理每种类型的命令。我还要求某些事件发送响应,以便系统的行为类似于事件驱动的远程过程调用。
例如,传感器设备可以具有计时器或响应命令来读取读数。然后它会格式化一个数据包并将其发送到 PC,PC 会响应它收到了该数据包。如果不是,则传感器设备可能会在超时时重新发送。
此外,当您进行网络传输时,您应该将其设计为网络堆栈,例如 OSI 模型 。 HDLC 是数据链路层和RPC 和命令处理是应用层。
I would use HDLC. I have had good luck with it in the past. I would for a point to point serial just use the Asynchronous framing and forget about all of the other control stuff as it would probably be overkill.
In addition to using HDLC for the framing of the packet. I format my packet like the following. This is how options are passed using 802.11
The total size of each command packet is len +2
You then define commands like
The other advantage is that you can add new commands and if you design your parser correctly to ignore undefined commands then you will have some backwards compatibility.
So putting it all together the packet would look like the following.
The system will then monitor the serial stream for the flag 0x7e and when it is there you check the length to see if it is pklen >= 4 and pklen=len+4 and that the crc is valid. Note do not rely on just crc for small packets you will get a lot of false positives also check length. If the length or crc does not match just reset the length and crc and start with decoding the new frame. If it is a match then copy the packet to a new buffer and pass it to your command processing function. Always reset length and crc when a flag is received.
For your command processing function grab the cmd and len and then use a switch to handle each type of command. I also require that a certain events send a response so the system behaves like a remote procedure call that is event driven.
So for example the sensor device can have a timer or respond to a command to take a reading. It then would format a packet and send it to the PC and the PC would respond that it received the packet. If not then the sensor device could resend on a timeout.
Also when you are doing a network transfer you should design it as a network stack like the OSI modle. The HDLC is the data link layer and the RPC and command handling is the Application Layer.