カスタマーサポートセンター

FAQ~よくある質問~ | FAQマスタ詳細表示

FAQ詳細情報

ID 10810771
FAQカテゴリ(大) C-SPYデバッガ
最終更新日 2016-01-10

質問内容

TN35170 チェックサム計算のデバッグ

回答内容

ターゲット:すべて
コンポーネント:一般
公開日: 2014年9月24日11時19分

 

導入
CRCの演算は「正しい」ことを立証することがとても難しいです正しい順序で正しいバイト シーケンスが処理されるか、またはそうではない場合があります。典型的な CRCアルゴリズムの 1 つの問題は、答えに近いことを確認する方法がないことです。はありません。

0x1000-0x3FFF のチェックサムを 多項式 0x1021 で計算する場合と、0x0100-0x3FFF のチェックサムを 多項式 0x1201 で計算する場合は別の結果になります。2 つのエラーのいずれかを発見し、新しい結果を得て、その結果が間違っているが、あなたが望むものに近いことを示していませんが、それが一致しない、これが得られる全てのすべての情報です。

次に、一般的な落とし穴とその処理方法の一覧を示します。

1.  外部チェックサムの範囲と、プログラムのチェックサムを計算したものを確認します。

チェックサムを生成するツールは、そのチェックサムを生成するために使用された範囲報告する必要があります。IAR XLINKリンカも ielftool ツールも両方の情報を提供します。報告された範囲がたとえば、0x40-0x3FFB、0x4000-0x7FFFであれば、チェックサムにそれらの正確なバイトを必要とし、ない0x40-0x7FFFまたはその他の変種であってはなりません。アドレス0x3FFC-0c3FFFのバイトがCRC計算の対象から除外されていることを確認する必要があります。

2. チェックサムが同じ多項式を使用していることを確認します。
同じチェックサム範囲でも、異なる多項式を使用する2つのチェックサムは一致しません。CRC-16は、多項式の値0x1021を持ちます。実際は0x11021ですが、MSBの1が16ビットに収まらないので通常廃棄されます。他の標準化された CRC値でも同じです。Xビット多項式のビットXはセットされますが、多項式のXビット表現に収まらないため含まれません (ビット0 から ビットX には X+1 ビット必要で X ビットには収まりません)。

多項式は、時々何かのX乗 + より小さいX乗 + etc という伝統的な数学的な多項式として表現さ​​れます。 この場合、多項式は、それぞれの X のビット位置を 1 とした対応する16進の数字に翻訳することができます。例:X ^ 16 + X ^ 12 + X ^ 5 + 1これは、ビット16、12、5、0 を使用します。0x10000 + 0x1000 + 0x20 + 0x1 = 0x11021 = 0x1021 = CRC-16

3. チェックサムが ミラーリング/反転で同じ表示をしていることを確認

ミラーリング/反転は時々CRC-アルゴリズムによって使用されます。ミラーリング/反転はバイト内のビットの順序を逆にすることによって行われます。

例:
 mirror(0x1) = 0x80
 mirror(0x17) = 0xE8
 mirror(0xE2) = 0x47
 mirror(mirror(x)) = x

一方のチェックサムがリフレクションを使用し、他方が使用していない場合、CRCアルゴリズムが効果的に異なるバイト列を検出しますから、チェックサムは、一般的には一致しません(バイト列はビット順が回文であるバイトを含めることができます)。反転/ミラーリングは通常、各インデックスバイトがビット逆順の256バイトの配列である、ミラーリングテーブルを介して処理されます。CRCコードは、ミラーテーブルのバイトを検索し、CRC計算のためのバイトの代わりに、テーブルエントリを使用します。

ミラーリング/反転の1つの問題は、使用するものが使用していることを知らないかもしれないということです。反転/ミラーリングが使用されているかどうかをテストする最も簡単な方法は、両方のバリアントを試してみて、どちらかの結果が一致するかどうかを確認することです。

4. アルゴリズムに追加バイトを与えるかも知れません

テーブル駆動型アルゴリズムを使用していない場合は、通常、バイト列が処理された後に追加の0バイトを処理する必要があります。チェックサムシンボルの各バイトに1つの0バイトが必要です。テーブル駆動型アルゴリズムを使用している場合は、追加のバイトは必要ありません。詳細はRoss N. Williams の "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS" を参照してください。

5. 正しいアドレス空間からバイトを読み込むことを確認します

注: これは、プロセッサが複数のアドレス空間を持っている場合のみ該当します。

正しいアドレス範囲でも、間違ったアドレス空間を処理することも、エラーの一因となる得ります。CRCアルゴリズムが使用するポインタが正しい型であることを確認してください、使用ポインタは正しいアドレス空間を指している必要があります。ポインタ宣言何かを記憶指定子を追加する必要があるかも知れません:

typedef __code unsigned char * CodePtr;

uint16_t

crc(uint16_t sum, CodePtr p, uint32_t len)

{

 .

 .

 .

}

 

6. 「大きい」の範囲で、「小さい」ポインタを使用する場合は注意してください

注: これはいくつかポインタ型があり1つが他の1つより狭い範囲をアクセスする場合に適用されます。

メモリ全体に達することができないポインタ(アドレス可能なメモリの64 K以上を持つシステム上で一般的に__nearポインタ)を使用している場合は、最後のアドレスに到達するときに問題が発生します。16ビット・ポインタの値が 0xFFFFの時、それをインクリメントすると0x0になり、0x10000番地にはなりません。もちろん間違ったバイトがチェックサムされます。

0x4000-0x27FFFの範囲のチェックサムを行いたい場合、すべてのアドレスに到達することができるポインタを使用する必要があり、小さなポインタを 0x24000回インクリメントし参照解除するだけでは十分ではありません。__nearポインタを使用して 0x4000番地からスタートすると、範囲0x4000-0XFFFF、0x0-0xFFFF、0x0-0x7FFF がチェックサムされ、期待している 0x4000-0x27FFF の範囲ではありません。通常__farまたは__hugeポインタを使用することで十分です。他の方法、__nearポインタを使用し、他の方法で 0x10000 と 0x20000 で切り替えることも可能ですが、大きいポインタを使用するとより安全です。

いずれにしても、64K以上の範囲のチェックサムをしたいということは、いくつかの方法で64kの境界線との交差を処理す​​る必要があることを意味します。

7. 小さく始めます

チェックサムが一致させるには、可能な限り小さな例で始まります。1バイトが多くの場合一番簡単で、テーブル駆動版では1回の読み出して、古典的なバージョンでは繰り返しは1回です。そこには境界交差はありません、それは両方のチェックサムが同じバイト値を使用するので、チェックは簡単です。

多項式、初期値、ミラー/反転アプローチとアドレス空間が同じであれば、チェックサムは同じになりますが、いくつかのケースでは、最終的なチェックサムは、1つの値 XOR されているか、1 または 2の補数になっています。

1バイトのチェックサムが一致したら、さらにいくつかのバイトをカバーするためにチェックサムを拡張することができます。これは使用する単一のバイトが偶然チェックサムが一致するいくつかの特別な性質を持っているリスクを最小化します(例えば 0 は反転ビュー内の不一致を検出できません)。マルチバイトのチェックサムが一致せず1バイトでは一致する場合、違うバイトでシングルバイトのチェックサムに戻ってください。

少し大きめの例で一致したら、範囲全体を試してみてください。小さな例では一致し大きな例では一致しない場合、ページ境界の問題 (16ビットアドレス境界)、チェックサムの位置 (チェックサムは通常チェックサム計算から除かれる)、予期されない内容を含む (このようなアドレスはチェックサムされるべきではない) かどうか、を調べてください。

8. 特殊なケース

標準的アプローチ(char型のポインタで 2つのアドレス間の各バイトを読み込む)で動作しない特別な場合は、もちろんあります。そのような例では、バイトを期待される順にアクセスするのにアセンブラのヘルプルーチンを使用する必要があるかもしれません。

また、別のフィルパターンを使用するのも役立ちます。多くは、フィルパターンに 0xFFを使用します。 もし、使用するマイコンのアーキテクチャが、すべての4番目のバイトを 0 と読み込む(いくつかのアーキテクチャは、「ゴーストバイト」を使用) 場合、一方はゴーストバイトに0xFFが使用され、もう一方、ハードウェア上のバイトがゴーストバイトのためには0x0を読み取りますから、チェックサムが1つも(オブジェクト・ファイルから生成されたものと)一致​​しません。この場合、フィル文字列 0xFFFFFF00を使用して(フィルは4バイトのアライメントされたアドレスで開始することを確認すること)、異なるチェックサムアルゴリズムが同じバイトを見ていることを確認します。

チェックサム範囲に、何らかの理由で予測不可能な値のバイトが含まれている場合は、そのバイトをチェックサムから除外するべきです。

 

すべての製品名は、各社の商標または登録商標です。

参考資料URL