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