协议帧解码策略

时间:2013-04-12 06:46:03

标签: c embedded protocols

我有以下问题:我在C中编写微控制器(ATmega 8bit,8051等)并通过UART接口接收自定义总线协议。我将接收到的字节放入缓冲区并稍后处理。

现在的问题是:是否有任何设计模式或策略来解码收到的帧?最好的方法是怎样做的?有没有书籍/教程?

这是我在这里的第一个问题,所以如果问题形成不好,请不要打我。)

2 个答案:

答案 0 :(得分:1)

由于所有这些协议都是自定义的,因此没有标准的方法来处理它们。唯一类似于ADT(或“设计模式”)的是数据的实际接收,通常通过ring buffer完成。

您通常用来解析实际协议的内容并不奇怪,但总是以相同的方式完成。你最终会得到这样的东西:

(我在下面的代码中使用前缀XYZ来表示该代码用于解码虚构的“XYZ”协议。将其替换为自定义协议的名称。)

// xyz.h
#ifndef XYZ_H
#define XYZ_H

typedef enum
{
  XYZ_OK,
  XYZ_ERR_SYNC,        // various error codes for things that can go wrong
  XYZ_ERR_LENGTH,
  XYZ_ERR_CHECKSUM,
  ...

} xyz_result_t;


xyz_result_t  xyz_decode (const uint8_t* buf, size_t n);

#endif /* XYZ_H */



// xyz.c
#include "xyz.h"

xyz_result_t  xyz_decode (const uint8_t* buf, size_t n)
{
  // various protocol-specific checks:

  if(buf[0] != SOME_SYNC_CHARACTER)
  {
    return XYZ_ERR_SYNC;
  }

  if(buf[something] < expected_min_length ||
     buf[something] > expected_max_length)
  {
    return XYZ_ERR_LENGTH;
  }

  ...

  return XYZ_OK;
}

答案 1 :(得分:0)

我发现设计协议很重要,因此很容易解码。我目前的一个具体的开始&amp;结束字节。因此,当UART接收到内容时,它知道数据包的起始位置(将缓冲区索引设置为零)以及它结束的位置(因此可以处理)。

如果你这样做,你需要“逃避”数据中的开始/结束字节,添加另一个字节。即0x7F - &gt; 0x7D,0x5F其中0x7D表示“下一个字节被转义”,0x5F表示转义的0x7F。

这使我的事情变得更容易。 IRQ很简单,没有/检查数据包很简单,然后很容易从数据包字节中获取数据。

IRQ

If (received byte == start flag)
    set receive buffer index to zero
else
    if (space left in buffer)
        store character in buffer
        if (received byte == end flag)
            process buffer

处理缓冲区

Unescape the packet data
Check length
Check checksum
Analyse data
相关问题