当前位置:  开发笔记 > 编程语言 > 正文

简单的串行点对点通信协议

如何解决《简单的串行点对点通信协议》经验,为你挑选了5个好方法。

我需要两个设备(PC和微控制器)之间的简单通信协议.PC必须向微软发送一些命令和参数.微必须传输一个字节数组(来自传感器的数据).

数据必须受到噪声保护(除了奇偶校验,我认为我还需要一些其他的数据校正方法).

有没有标准的解决方案呢?(我只需要一个想法,而不是完整的解决方案).

PS任何建议表示赞赏.PPS对不起任何语法错误,希望你理解.

编辑1.我还没有决定它是主/从协议还是双方都可以发起通信.PC必须知道微工作何时完成工作并且可以发送数据.如果数据准备就绪,它可以连续轮询微观,或者当作业完成时微观可以发送数据.我不知道哪个更好更简单.

编辑2. 硬件和物理层协议.由于PC中使用RS-232 C串行标准,我将使用异步通信.我将只使用RxD,TxD和GND信号.我无法使用额外的电线,因为微控制器AFAIK不支持它们.顺便说一下,我正在使用AVR ATmega128芯片.

所以我将使用固定波特率,8位数据,2个停止位而不进行奇偶校验(或使用?).

数据链路协议.这就是我的问题主要关注的问题.感谢您提出HDLC,PPP和Modbus协议.我会研究它.



1> Rex Logan..:

我会用HDLC.我过去好运.我想要点串口只使用异步框架并忘记所有其他控件的东西,因为它可能是矫枉过正.

除了使用HDLC进行数据包的成帧.我格式化我的数据包如下.这是使用802.11传递选项的方式

U8 cmd;
U8 len;
u8 payload[len];

每个命令包的总大小为len +2

然后,您可以定义命令

#define TRIGGER_SENSOR 0x01
#define SENSOR_RESPONSE 0x02

另一个优点是您可以添加新命令,如果您正确设计解析器以忽略未定义的命令,那么您将具有一些向后兼容性.

所以将数据包放在一起看起来如下所示.

 // total packet length minus flags len+4
 U8 sflag;   //0x7e start of packet end of packet flag from HDLC
 U8 cmd;     //tells the other side what to do.
 U8 len;     // payload length
 U8 payload[len];  // could be zero len
 U16 crc;
 U8 eflag;   //end of frame flag

然后系统将监视串行流的标志0x7e,当它在那里时,你检查长度,看它是pklen> = 4和pklen = len + 4,并且crc是有效的.注意不要只依靠crc来获取小包,你会得到很多误报也检查长度.如果长度或crc不匹配,只需重置长度和crc,然后从解码新帧开始.如果匹配则将数据包复制到新缓冲区并将其传递给命令处理函数.收到标志时,始终重置长度和crc.

对于命令处理函数,请抓取cmd和len,然后使用开关来处理每种类型的命令.我还要求某些事件发送响应,因此系统的行为类似于事件驱动的远程过程调用.

因此,例如,传感器设备可以具有计时器或响应命令以获取读数.然后它会格式化数据包并将其发送到PC,PC将响应它收到的数据包.如果没有,则传感器设备可以在超时时重新发送.

此外,当您进行网络传输时,您应该将其设计为像OSI模块一样的网络堆栈,因为Foredecker点不会忘记物理层的内容.我在HDLC上的帖子是数据链路层,RPC和命令处理是应用层.



2> Foredecker..:

RS232协议很棘手.使用HDLC的建议是一个很好的建议,但它不是整个解决方案.您还需要决定其他事项:

如何确定两个设备之间的波特率?Autobuad?预定义,还是设置explicate?

你会用软件或硬件或两者进行流量控制吗?请注意,如果使用硬件流控制,则必须确保电缆正确构建.

说到电缆,这对RS233来说是一个巨大的痛苦.根据设备的不同,您可能需要使用直通电缆,交叉电缆或变体.

使用基于软件的流量控制机制可以是有效的,因为它允许使用最简单的电缆 - 只有三个有线(TX,RX和公共).

你选择7位或8位字吗?

硬件奇偶校验或软件错误检查.

我建议你使用8个数据位,没有硬件奇偶校验,1个停止位,并使用基于软件的流量控制.如果您的硬件支持,您应该使用自动波特率.如果没有,那么autobaud在软件中非常困难.



3> Tom Leys..:

这里有一些很好的答案,这里有一些有用的指示:

即使您的数据包没有时间分隔,同步字节也是减少尝试构建数据包所需位置数量的重要方法.您的设备通常必须处理一堆垃圾数据(即打开时飞行中数据包的末尾,或硬件冲突的结果).如果没有同步字节,您将不得不尝试从接收到的每个字节中生成数据包.同步字节意味着只有1/255字节的随机噪声可能是数据包的第一个字节.当您想要窥探您的协议时也很神奇.

当您通过某种类型或其他类型的窥探工具查看数据包时,在您的数据包上有一个地址,甚至只是说主/从或PC /设备有用.您可以通过为PC提供与DEVICE不同的同步字节来实现此目的.此外,这将意味着设备不会响应其自身的回声.

您可能希望查看纠错(例如汉明).将8位数据打包成12位受保护字节.这12位中的任何一位都可以在途中翻转并检索原始的8位.用于数据存储(用于CD)或设备无法轻松重新发送(卫星链接,单向射频).

数据包编号使生活更轻松.发送的数据包带有一个数字,响应携带相同的数字和一个标记为"响应"的标志.这意味着发送方很容易检测到从未到达的数据包(同步已损坏的数据),并且在具有慢速链接的全双工模式下,可以在收到第一个响应之前发送两个命令.这也使协议分析更容易(第三方可以理解在不知道底层协议的情况下收到了哪些数据包)

拥有一个主人是一个很棒的简化.也就是说,在全双工环境中,它根本不重要.我只想说你应该总是这样做,除非你试图节省电力或者你正在设备端做一些事件驱动(输入状态改变,样品就绪).



4> Martin Liesé..:

我的建议是modbus.它是一种高效且简单的标准协议,用于与具有传感器和参数的设备(例如PLC)进行通信.您可以在http://www.modbus.org上获取规范.它自1979年以来一直存在并且越来越受欢迎,您可以毫无困难地找到示例和库.



5> Ken Tindell..:

几个月前我读过这个问题,问题完全相同,并且没有真正找到任何有效的东西,只需要一个微小的8位微内存.因此受到CAN和LIN的启发,我建立了一些工作.我叫它MIN(微控制器互连网络),我把它上传到GitHub:

https://github.com/min-protocol/min

这里有两个实现:一个在嵌入式C中,一个在Python中用于PC.加上一个小的"hello world"测试程序,PC发送命令,固件点亮LED.我在博客上写到了如何在Arduino板上运行并运行:

https://kentindell.wordpress.com/2015/02/18/micrcontroller-interconnect-network-min-version-1-0/

MIN非常简单.我修复了第0层表示(8个数据位,1个停止位,无奇偶校验),但保持波特率打开.每帧以三个0xAA字节开始,二进制为1010101010,如果一端想要动态适应另一端,则可以进行自动波特率检测.帧是0-15字节的有效载荷,具有16位Fletcher的校验和以及控制字节和8位标识符(告诉应用程序有效载荷数据包含的内容).

该协议使用字符填充,以便0xAA 0xAA 0xAA始终指示帧起始.这意味着如果设备退出复位,它总是与下一帧的开始同步(MIN的设计目标永远不会传递不完整或不正确的帧).这也意味着不需要具有特定的字节间和帧间时序约束.该协议的完整细节在GitHub repo wiki中.

MIN有未来改进的空间.我在那里留下了一些钩子用于块消息传递(保留4位控制字节)和更高级别的能力协商(标识符0xFF保留),因此有足够的空间来添加对常用功能的支持.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有