[英]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.