簡體   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