jpa*_*ker 39 embedded serial-port
我有一个嵌入式系统,我正在通过串口进行通信.现在,命令结构旨在以交互方式操作:它显示提示,接受一些命令,并以人类可读的形式显示结果.
我正在考虑将其更改为更加机器可用的格式,因此我可以通过MATLAB GUI与它进行对话而不会有太多麻烦(现在它正在打扰交互式提示和不同的消息长度等).
那么是否有某个文档或标准描述了如何为嵌入式系统设计良好的串行命令协议?
Bru*_*Gee 50
我有一些偏好(和烦恼)从编写软件到使用RS232控制媒体和显示设备.根据您的硬件,其中一些可能不适用:
我认为让协议对自动化更友好是一个好主意.如果需要交互式界面(命令行或其他),请单独构建它并使其使用自动化协议.我不会太担心让人类可读,但这取决于你.
如果您收到无效命令,则始终(特别是)返回响应.一些简单的东西,如06美元的ACK和15美元的NAK.或者如果你想让它更具人性化,请拼写出来.
如果您可以设置任何值,请确保有一些方法可以查询相同的值.如果您有很多值,可能需要一段时间才能查询所有值.考虑让一个或几个元数据一次返回多个值.
如果您有无法设置的信息,但很重要(型号,序列号,版本,版权等),请确保可以查询这些信息,而不是仅在启动或重置时显示一次.
永远不要回复有效命令的错误.你会认为这个很明显......
说到明显,请记录硬件支持的串行设置.特别是如果它将被除你以外的任何人使用,并且你不希望他们花费前30分钟试图弄清楚他们是否因为串口,连接,电缆或者无法与设备通话他们的软件.不是说我很苦......
使用绝对命令而不是切换值.例如,为开机和关机提供单独的命令,而不是发送相同的命令并打开和关闭电源切换.
响应应包括有关它们响应的命令的信息.这样,任何程序都不需要记住它为处理响应而要求的最后一件事(请参阅下面的额外信用选项).
如果您的设备支持待机模式(关闭但不是真正关闭),请确保在您处于此状态时查询仍然有效.
根据您对数据完整性的偏执程度:
将信息包裹在信封中.标题可以包括起始字符,消息的lengeth和结束字符.以防您收到部分或格式错误的邮件.开始时可能是02美元,最后可能是03美元.
如果您对消息完整性非常偏执,请包括校验和.不过,他们可能会有点痛苦.
额外信用:
我希望这有帮助.
更新:
我忘记了重要的事情.在你严肃地使用它之前,特别是在你把它交给别人之前,试试一些微不足道的东西,以确保它按照你期望的方式工作,并且(更重要的是)确保你没有留下任何东西.如果您在更大的项目中发现问题,则需要花费更多的时间和精力来解决问题.
无论您是在设计命令协议,Web服务,数据库架构还是类等,这都是一个很好的经验法则.
Mar*_* MD 15
以下是Eli Benderski关于串行协议框架的精彩文章.无论您选择哪种数据包格式,请务必使用转义字符.它允许您在实际数据中包含此类字符,并使数据包损坏时重新同步非常容易.
除非带宽或延迟是一个大问题,否则请尽可能使用ASCII - 它使调试变得更加容易.
我喜欢发送消息的协议,然后是一个明确的'消息结束'字符(例如'回车').我通常不会发现数据包信号的开始是有用的(该线路上还有什么?)使用CR进行消息结束也使得通过终端程序进行测试变得更容易.
更新:Bruce指出(在评论中)数据包字符的开头可以让您在损坏的情况下更快地找到数据包.如果没有数据包字符的开头,则在您知道自己的位置之前,它将一直持续到下一个数据包的末尾,此时您将丢弃2个数据包而不是一个数据包.
小智 6
我喜欢Bruce McGee的答案.使用类似的接口后,我可以提供其他几个指针:
在数据包中返回数字类型时,请尝试使所有内容都相同.对于某些数字不要单独,对其他数字不要双.并且不要随意!
提供ICD中数据包的示例.必须猜测字节顺序甚至是位顺序是非常令人沮丧的(首先是MSByte,还是最后一个?什么是第一个和最后一个?).提供一个显示数据包与时间的关系图(即最早发送0x02,然后是地址字节,然后是消息ID等).
如果可能的话,不要在数据格式之间切换.我曾在一些系统中使用'ASCII编码数字'来处理某些消息,你必须从字节中删除前导'3',然后将它们拉到一起以形成实数.(通常使用ASCII编码,当你有一个必须避免的字节序列,如0x02,0x04等.编码的数字将是0x30,0x32,0x30,0x34.如果可能的话,使用长度字段来避免这种情况,或者至少一直这样做!)
绝对绝对肯定会记录波特率,奇偶校验等.如果你正在使用RS-485文件总线模式(2线?4线?)或任何设置将出现在你打算用于它的机器上.如果必须,请提供屏幕截图.
这个接口可能对调试非常有用.我使用过一些具有调试功能的系统,例如:
程序员制作"已记录参数"列表(内部变量)的系统.您可以告诉系统您想要报告哪些(最多8个),然后当您向系统查询已记录的参数时,它会将它们返回到一个数据包中.我喜欢这个,但是根据系统的复杂程度,你可能会或者可能无法在运行时指定它们(或者你可以做一些简单的事情并向系统发送一个掩码,选择你想要返回的掩码).
数据包"破坏"行为并允许系统的各个部分独立测试(即,在D/A上输出此电压,在DIO端口上激励此字节等)
祝好运!
如果您必须拥有自己的协议,
请请使用包框架.
SLIP仅构建几行代码.在(RFC 1055)中指定
所以现在所有的数据包总是这样
<slip packet start>
message
message crc
<slip packet start>
Run Code Online (Sandbox Code Playgroud)
不要发送消息长度.它可能会被破坏,然后接收者消息解析器会混淆.
如果你的接收器有一个小的接收器缓冲区并且它溢出,你只需继续读取直到数据包边界.没有伤害.
大量简单的2字节CRC; Xmodem很容易.您只需要清除数据包中的所有字节即可.
如果你想成为一个非常好的人,请使用PPP,DDNS和HTTP-REST作为实际命令.关于在16位系列PIC处理器上做这件事的可爱的书,由杰里米·本特姆,TCP/IP精益.
然后,您可以使用Web浏览器与其进行通信,或者使用来自C代码的libcurl.由于几乎每种编程语言都有可以执行http的库,因此每个人都可以与您的设备通信.