5

最初にいくつかの背景。何らかの理由でファームウェアがクラッシュすると (スタック オーバーフロー、関数ポインタの破損など)、どこかにジャンプして何らかのコードの実行を開始することがあります。これにより、遅かれ早かれウォッチドッグがリセットされます。MCU はリセットされ、軌道に戻ります。そうでもなければ...

フラッシュに書き込むコード (ブートローダなど) がある場合はどうでしょうか? ここで、すべてのチェックをスキップして、誤ってフラッシュ書き込みコードに直接ジャンプしてしまう可能性があります。ウォッチドッグが吠える前に、ファームウェアが破損することになります。これはまさに私に起こっていたことです。

今、一部の人は言うかもしれません - コードの記述に飛び込む原因となった根本的なバグを修正してください。開発中は常にコードを変更しています。現時点でそのようなバグがなくても、明日はあるかもしれません。その上、バグのないコードはありません - または少なくとも私のものではありません。

だから今、私はある種のクロスチェックを行っています。「wen」という名前の変数があり、通常のチェック (宛先が有効であることを確認するなど) の前に 0xa5 に設定します。次に、実際の消去または書き込みを行う直前に、「wen」が本当に 0xa5 に設定されているかどうかを確認します。それ以外の場合、これは何らかの形で誤ってコードの記述に飛び込んだことを意味します。書き込みが成功すると、「wen」はクリアされます。私はこれをCで行いましたが、うまくいきました。ただし、理論的には破損が発生する可能性がわずかにあります。これは、この「wen」の最終チェックから SPMCR レジスタへの書き込みまでの命令がほとんどないためです。

ここで、このチェックを SPMCR への書き込みと spm 命令の間のアセンブリに入れることで、これを改善したいと考えています。

__asm__ __volatile__
(   
    "lds __zero_reg__, %0\n\t"
    "out %1, %2\n\t"
    "ldi r25, %3\n\t"
    "add __zero_reg__, r25\n\t"
    "brne spm_fail\n\t"
    "spm\n\t"
    "rjmp spm_done\n\t"
    "spm_fail: clr __zero_reg__\n\t"
    "call __assert\n\t"
    "spm_done:"
    :
    : "i" ((uint16_t)(&wen)),
      "I" (_SFR_IO_ADDR(__SPM_REG)),
      "r" ((uint8_t)(__BOOT_PAGE_ERASE)),
      "M" ((uint8_t)(-ACK)),
      "z" ((uint16_t)(adr))
   : "r25"
);

コードはまだ試していません。明日試してみます。問題はありますか?そのような問題をどのように解決しますか?

4

2 に答える 2

3

私が見た 1 つの手法は、フラッシュ書き込みルーチンの直前のバイトがある種のウォッチドッグ タイムアウトをトリガーするか、プロセッサをリセットすることです。そうすれば、フラッシュ書き込み関数に至るまでのランダム データを実行することはできず、単に関数に「陥る」ことはありません。

命令が正しく解釈されるように、リセットする前にいくつかの NOP が必要になる場合があります。

関数が最初から実行されたことを確認する手法はwen、書き込みが完了したら変数をクリアすると仮定すると、良い手法のように見えます。

于 2012-02-17T00:12:05.047 に答える
2

ブートローダーでフラッシュに書き込む機能が必要な理由がわかりません。私たちのブートローダは、シリアル ポート経由でアプリケーション プログラムを更新できるため、そうします。そのため、フラッシュに書き込むコードがローダーに含まれないようにすることで、不注意による書き込みの可能性を排除しています。ダウンロードされるコードは、書き込まれるイメージを含む同じパッケージのヘッダーです。オンボード イメージにはプログラミング アルゴのチェックサムが格納されており、実行前に検証されます。

内部で生成されたものを書いている場合は、ハードウェア関連のインターロックを調べます。以前に特定のディスクリート出力ピンを ON に設定したことがある場合にのみ、書き込みを許可してください。「IP がチェックを通過したらどうなるか」という問題に答えるには? あなたは2つの部分でそれを行うことができます. まず、アルゴリズムのいくつかの重要な変数を設定します。(たとえば、書き込み先のアドレス-無効なメモリに初期化されたままにし、書き込み前に行われた別の呼び出しでのみ正しく設定します。次に、書き込み機能にHWインターロックをチェックさせます。割り込みで有効化ステップの1つを実行します。または、タイマーに応答して、不正な IP を使用している場合、正しい順序でヒットする可能性が低いもの。

IP が本当にどこにでもジャンプできる場合、不注意による書き込みを防ぐことは不可能かもしれません。期待できる最善の方法は、そこに到達するための唯一のパスが、書き込みを成功させるために必要な他のすべてをセットアップすることです。

于 2012-02-17T15:06:43.303 に答える