質問

Motorola HCS08マイクロコントローラーアプリケーションにCRC16エラー検出を追加しようとしています。しかし、私のチェックサムは一致しません。 1 オンラインCRC計算機 PCプログラムで表示される結果と、マイクロで表示される結果の両方を提供します。

Microの結果を「Xmodem」と呼び、PCの結果「Kermit」と呼びます。

これら2つの古代プロトコルがCRC16の使用を指定する方法の違いは何ですか?

役に立ちましたか?

解決

同じ基本コードベースを使用して、16ビットIBM、CCITT、Xmodem、Kermit、およびCCITT 1D0Fを実装できます。見る http://www.acooke.org/cute/16bitcrcal0.html からのコードを使用します http://www.barrgroup.com/embedded-systems/how-to/crc-calculation-code

次の表は、それらがどのように異なるかを示しています。

name    polynomial  initial val  reverse byte?  reverse result?  swap result?
CCITT         1021         ffff             no               no            no
XModem        1021         0000             no               no            no
Kermit        1021         0000            yes              yes           yes
CCITT 1D0F    1021         1d0f             no               no            no
IBM           8005         0000            yes              yes            no

ここで、「逆バイト」とは、各バイトが処理される前にビットリバーがあることを意味します。 「逆結果」とは、16ビットの結果が処理後にビット反転が行われることを意味します。 「スワップ結果」とは、結果の2つのバイトが処理後に交換されることを意味します。

上記のすべては、テストベクトルに対して検証されました http://www.lammertbies.nl/comm/info/crc-calculation.html (それが間違っている場合、私たちはすべて失われています...)。

したがって、特定のケースでは、各バイトをビットリバーすることにより、Xmodemのコードをカーミットに変換し、最終結果をビット反転させてから、結果の2つのバイトを交換できます。

私は信じていますが、各バイトを逆転させることは、多項式の反転と同等であることを確認していませんが、詳細を確認していません(およびいくつかの追加の詳細)。これが、基本的に同じアルゴリズムであるものについて、さまざまな場所に非常に異なる説明が表示される理由です。

また、上記のアプローチは効率的ではありませんが、テストに適しています。効率的にしたい場合は、上記をルックアップテーブルに翻訳することです。

編集 私が上記のccittと呼んだものは、 Revengカタログ ccitt-falseとして。詳細については、上記のリンクのブログ投稿の更新を参照してください。

他のヒント

私の回想(以前は、以前はモデムの材料をやり直していましたが)は、Kermitが最初に最小のビットを使用してデータの各バイトのビットを処理することです。

ほとんどのソフトウェアCRC実装(Xmodem、おそらくXmodem)は、最初に最も重要なビットでデータバイトを実行します。

ライブラリソースを見るとき(それをダウンロードしてください http://www.lammertbies.nl/comm/software/index.html)リンクしたCRC計算ページに使用すると、XmodemがCRC16-CCITTを使用していることがわかります。

x^16 + x^12 + x^5 + 1  /* the '^' character here represents exponentition, not xor */

多項式はビットマップで表されます(ビット16が暗示されていることに注意してください)

0x1021 == 0001 0000 0010 0001  binary

カーミットの実装は次のとおりです。

0x8408 == 1000 0100 0000 1000  binary

これはXmodemのビットマップと同じビットマップであり、逆転しています。

ライブラリに付随するテキストファイルは、カーミットの次の違いについても言及しています。

CRC-KermitおよびCRC-Sickのみ:すべての入力処理の後、CRCの補体が計算され、CRCの2バイトが交換されます。

したがって、PCの結果に合わせてCRCルーチンを変更するのはおそらく簡単なはずです。 CRCライブラリのソースには、かなりリベラルなライセンスがあるように見えることに注意してください。多かれ少なかれ使用することは理にかなっているかもしれません(少なくともアプリケーションに適用される部分)。

X-Modem 1K CRC16。

入力データ{0x01、0x02}および多項式0x1021を使用して、bytewise crc-16のプロセス

  1. init crc = 0
  2. 最初の入力バイト0x01:2.1 'xor-in'最初の入力バイト0x01は、CRCのMSB(!)への最初の入力バイト0x01:0000 0000 0000 0000(CRC)0000 0001 0000 0000(入力バイト0x01左シフトで8)


    0000 0001 0000 0000 = 0x0100この結果のMSBは、現在のDivident:MSB(0x100)= 0x01です。 2.2したがって、0x01は分割です。テーブルからDividentの残りを取得します:crctable16 [0x01] = 0x1021。 (まあ、この値は上記の手動計算からのファミラです。)現在のCRC値は0x0000であることを忘れないでください。現在のCRCとXORのMSBを現在の残りの部分でシフトして、新しいCRC:0001 0000 0010 0001(0x1021)0000 0000 0000 0000(CRC 0x0000左シフトで8 = 0x0000)を取得します


    0001 0000 0010 0001 = 0x1021 =中間CRC。

  3. 次の入力バイト0x02を処理:現在、中間CRC = 0x1021 = 0001 0000 0010 0001があります。バイト0x02左シフト8)


    0001 0010 0010 0001 = 0x1221この結果のMSBは、現在の分割です:MSB(0x1221)= 0x12。 3.2したがって、0x12は分割です。テーブルからDividentの残りを取得します:crctable16 [0x12] = 0x3273。現在のCRC値は0x1021であることを忘れないでください。現在のCRCとXORのMSBを現在の残りの部分とともにシフトして、新しいCRC:0011 0010 0111 0011(0x3273)0010 0001 0000 0000(CRC 0x1021左シフトで8 = 0x2100)を取得します


    0001 0011 0111 0011 = 0x1373 =最終CRC。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top