各テレメトリ フレームの末尾に 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