繁体   English   中英

协议帧解码策略

[英]Strategy for protocol frame decoding

我遇到以下问题:我正在用C对微控制器(ATmega 8bit,8051等)进行编程,并通过UART接口接收了自定义的总线协议。 我将接收到的字节放入缓冲区中,然后再处理。

现在的问题是:是否有任何设计模式或策略可以对接收到的帧进行解码? 如何做到这一点的最佳方法? 有书籍/教程吗?

这是我的第一个问题,如果问题的格式不正确,请不要打我:)

由于所有此类协议都是自定义的,因此没有标准的方法可以照此处理。 唯一类似于ADT(如果需要的话,就是“设计模式”)是实际的数据接收,通常是通过环形缓冲区来完成的。

通常,解析实际协议所做的事情并不花哨,但总是以相同的方式完成。 您最终将得到如下结果:

(我在下面的代码中使用前缀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;
}

我发现设计协议以使其易于解码非常重要。 我当前的那个有特定的开始和结束字节。 因此,当UART接收到信息时,它便知道数据包在何处开始(将缓冲区索引设置为零)以及在何处结束(以便可以进行处理)。

如果执行此操作,则需要“转义”数据中的开始/结束字节,并添加另一个字节。即0x7F-> 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM