各テレメトリ フレームの末尾に CRC を追加するハードウェア CRC ジェネレータを通過するテレメトリ ストリームがあります。現在、ハードウェアで生成された CRC を検証するために何かを作成しようとしています。正しいCRCを計算する(複数回検証された)古いレガシーコード(以下を参照)があります。ただし、各テレメトリ フレームは 300 バイト以上であり、処理するフレームが 10,000,000 以上になる可能性があるため、低速です。
いくつかの調査の後、テーブル駆動型のアプローチを示している文献をいくつか見つけました。従来の方法では、0x8005 の Poly を使用し、処理前に各バイトのビット順序を逆にし、CRC をゼロに初期化します。ただし、反転入力と非反転入力を使用してそのポリゴンのテーブルを作成し、データの最初のバイト (0x10) でさえ処理しようとした後、従来の方法が生成しているものと一致するものを取得できません。
calcCRC16 関数 (以下) 内では、既存のメソッドは LSB をチェックしますが、他のメソッドは MSB をチェックしているように見えます...そして、ビット シフトは右側にあり、私が見た他の例は左側にあります。特に、この関数に渡す前にビット順序が交換されるため、これがなぜなのかわかりません。私はオンライン計算機を試してみました & 8005 から A001 (反転)、通常および反転入力バイト、および私が考えることができるすべての組み合わせにテーブルで手動でルックアップを行いますが、一致するテーブルアプローチを取得できませんハードウェア実装に適していることがわかっているレガシーコード。
明らかな何かが欠けている場合、誰かが私を助けてくれますか? 同じ出力を作成するためにテーブルベースのアプローチを作成するにはどうすればよいですか? 私は C++ の初心者であり、CRC 生成にあまり詳しくなく、基本的なことを見落としている可能性があります。ハードウェア CRC に対して検証されたサンプル コードと出力は次のとおりです。
サンプル コード:例として、既知のテレメトリ ストリームから数バイトをハード コードしました。
/** ********************************************************************************
* TEST CRC METHOD
*******************************************************************************/
#include <iostream>
using namespace std;
unsigned char swapBits(unsigned char d);
void calcCRC16(unsigned int *CRCVal, unsigned char value);
/** **************************************************************************
*   @function   main
*   TEST CRC METHOd
*******************************************************************************/
int main(int argc, char* argv[])
{
    short          dataLength = 5;
    unsigned int   givenCrc;
    unsigned int   calcCrc;    
    unsigned char byte[] = {0x10,0xbb,0x42,0x4d,0xfd};
    /* Init CRC. */
    calcCrc = 0;
    cout << "Inital CRC = " << hex << calcCrc << "\n";
    /* Read frame data. */
    for (int i = 0; i < dataLength; i++)
    {
        cout << "byte    = " << hex << static_cast<int16_t>(byte[i]) << " ";
        calcCRC16(&calcCrc, swapBits(byte[i]));
        cout << "calcCRC = " << hex << calcCrc << "\n";
     }
}
/** ********************************************************************
*   @function   swapBits
*   Swaps the bits so they match the order sent to CRC Gen Hardware
************************************************************************/
unsigned char swapBits(unsigned char d)
{
    unsigned char t = 0;
    int i           = 0;
    int n           = 0x80;
    for(i=0x01; i<0x100; i=i<<1)
    {
        if (d & i)
        {
            t|=n;
        }
        n=n>>1;
    }
    return t;
}
/** ********************************************************************
*   @function   calcCRC16
*   WORKING METHOD VERIFIED AGAINST CRC HARDWARE
************************************************************************/
void calcCRC16(unsigned int *CRCVal, unsigned char value)
{
    unsigned char lsb;
    unsigned char bcnt;
    for (bcnt=0 ; bcnt<8 ; bcnt++)
    {
        lsb = (value ^ *CRCVal) & 0x01;
        *CRCVal >>= 1;
        value >>= 1;
        if (lsb != 0)
        {
            *CRCVal ^= 0x8005;
        }
    }
}
出力:
    初期 CRC = 0
    バイト = 10 calcCRC = b804
    バイト = bb calcCRC = 1fb8
    バイト = 42 calcCRC = 461d
    バイト = 4d calcCRC = 3d47
    バイト = fd calcCRC = 683e