Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C语言设计主(PC或ARM板)和从(微处理器)之间简单而健壮的串行协议_C_Serial Port_Embedded_Protocols_Firmware - Fatal编程技术网

用C语言设计主(PC或ARM板)和从(微处理器)之间简单而健壮的串行协议

用C语言设计主(PC或ARM板)和从(微处理器)之间简单而健壮的串行协议,c,serial-port,embedded,protocols,firmware,C,Serial Port,Embedded,Protocols,Firmware,我想在两个设备之间创建一个简单而健壮的通信协议:主设备和从设备。主设备可以是pc或arm iMX6 bard或具有QT或Visual Studio应用程序的等效板,而从设备可以是AVR或微芯片等微处理器。我想找到最好的解决方案,在它们之间设计一个简单而健壮的串行协议。我考虑过两种可能的解决方案,但也许还有其他的解决方案 第一种解决方案-同步通信 主机发送启动命令(一个字节) 从机用START_ACKNOLEDGE应答(一个字节) MASTER发送命令(更多字节,末尾有校验和字节) 从机用命令_A

我想在两个设备之间创建一个简单而健壮的通信协议:主设备和从设备。主设备可以是pc或arm iMX6 bard或具有QT或Visual Studio应用程序的等效板,而从设备可以是AVR或微芯片等微处理器。我想找到最好的解决方案,在它们之间设计一个简单而健壮的串行协议。我考虑过两种可能的解决方案,但也许还有其他的解决方案

第一种解决方案-同步通信

主机发送启动命令(一个字节)

从机用START_ACKNOLEDGE应答(一个字节)

MASTER发送命令(更多字节,末尾有校验和字节)

从机用命令_ACKNOLEDGE(一个字节)应答,如果有必要,用 信息包的某些字节(某些字节末尾带有校验和字节)

带数据包的主应答\u ACKNOLEDGE(一个字节)

MASTER发送命令_END(一个字节)

从机必须在1毫秒或2毫秒内响应主机。 使用此解决方案,主设备很容易检查通信,如果从设备没有应答,或者如果从设备在1或2 ms内没有应答,或者如果从设备发送的数据包校验和不正确,则主设备可以再次发送该命令。从另一方面来说,这个协议是一个同步通信协议

第二种解决方案:

主设备通过以下结构向从设备发送命令:

起始字节:0xAA(10101010)

命令字节:一个字节(不同于0xAA、0xCC、0x33、0xC3或0x3C)

数据长度:一个字节,包含数据字节数的信息(是否有必要?)

数据字节:一个或多个字节

校验和:一个字节

结束字节:0xCC 0x33 0xC3 0x3C(11001100001100111100001100111100)

在这种情况下,从机可以使用带有两个指针的循环缓冲区,它可以执行如下操作:

if(RxStart!=RxStop)
{
 while((RxStop>=RxStart)&&(RxStop-RxStart>=X+4))
 {
  if(RxBuff[RxStart & 0xFF]==0xAA && RxBuff[(RxStart+X) & 0xFF]==0xCC &&    
  RxBuff[(RxStart+X+1) & 0xFF]==0x33  &&  RxBuff[(RxStart+X+2) & 0xFF]==0xC3 
  && RxBuff[(RxStart+X+3) & 0xFF]==0x3C)
  {
   if(CheckSum==OK) 
   {
    switch(RxBuff[RxStart+1 & 0xFF])
    {

    }
   }
  }
 }
} 
在这种情况下,主机如何检查发送给从机的命令是否已收到?从属设备是否必须向主设备发送命令的acknoledge(例如,acknoledge的一个字节和包含命令信息的一个字节)?主机是否必须检查从机是否在1ms内响应命令?主机是否必须检查从从机接收的acknoledge的编号? 如果从从机接收的acknoledge小于主机发送的命令,主机如何理解哪个命令已丢失? 让我知道


非常感谢您的支持

我想就此发表评论,但我还没有这个名声:)

你为什么要回避这些标准?i2C、SPI、UART

如果您需要一个基于软件的协议,下面有一些很好的例子可以为您的协议建模:

如果您确实想选择一个标准,这里有一个很好的比较页面,可以找出您需要的标准:
你的方法有一些缺陷

首先,假设可以在两毫秒内来回发送数据。这在windows下不起作用。你必须处理USB到串行转换器,它们自己进行缓冲,你还必须处理操作系统,这些操作系统可能会阻止你的应用程序长时间接收,因为它可能有更好的事情要做。另外,其他进程可能会阻止您再运行十次。(病毒扫描器)

第二:您的协议没有防止数据损坏的保护。我看不出使用校验和来防止数据损坏。如果串行线路出现问题,您可能会陷入死锁

第三:您的协议效率不高,因为即使没有出现任何问题,您仍然需要在主设备和从设备之间来回发送一些重要的命令或数据帧。这会减慢速度


幸运的是,这个问题并不新鲜。有几种协议可以解决上述所有问题。HDLC就是一个例子。还有一种更简单的变体称为SHDLC。一个好的实现将是坚如磐石的、快速的,并解决我所批评的所有问题。

我的方法是首先定义您的实际硬件(主机、连接等),以便您知道您的协议必须面对哪些挑战。还有,您有多少不同的命令?他们要多久?我们有什么时间限制?从机有多少线程?所有这些(以及更多)都需要解决

如果您使用的是rs232(我最熟悉的一种),那么假设实际传输线上不会出现数据包丢失是相对安全的。如果您使用的是网络,则不会出现这种情况

关于2ms超时太短的想法绝对是正确的。如果您将PC端实现为windows驱动程序,则可以减少此问题。1秒钟的超时时间非常长

你的第一个协议非常健谈。该协议实际上包含多个命令。实际上,您已经将一个命令包装为多个命令,但这并不能解决问题,只是将其隐藏起来,使其不那么常见

我会做一些简单的事情,比如:

  • 主机发送完整命令和校验和
  • 从机在某个超时时间内发送ACK
  • 如果主机在超时时间内没有收到ACK,它将再次发送命令
  • 此协议假定您可能遇到的唯一问题是 *有些位已损坏。这是固定的,从机执行校验和 *首次发送命令时,从机太忙,某些字节被丢弃。这在执行校验和后通过ACK修复


    你还看到了什么问题?如果您需要一个功能强大的协议,为什么不使用以太网和TCP进行连接呢?

    我将尝试回答OP和mak的其他评论