WDTとは
ウォッチドッグタイマー(WDT:WatchDog Timer)は暴走やフリーズ(ハングアップ)したシステムをリセットして、正常動作に戻すことを目的としたタイマー機能です。ウォッチドッグは番犬という意味で、システムがフリーズしていないかを常に監視しています。殆どのマイコンに組み込まれている基本的な機能の1つです。
WDTの仕組み
WDTの仕組みは単純です。起動と同時に内部のカウント値を繰り上げていき、カウント値がオーバーフロー(リミット超え)するとマイコンをリセットします。そうならないためにマイコンは、WDTのカウント値をクリアーし続けなければなりません。 実際の動作は次の通りです。マイコンのプログラムの中に、WDTのカウント値を定期的にクリアーする処理を組み込みます。プログラムが正常に動いている限り、カウント値は定期的にクリアーされてWDTが働くことはありません。しかしひとたびプログラムが暴走してカウント値がクリアーされなくなると、カウント値がオーバーフローしてプログラムは再起動されます。
WDTを使う際の注意点
- 最大処理時間を把握する
-
プログラムの中に定期的にカウント値をクリアーする処理を入れていたとしても、それが常に一定以下のタイミングで働き続けなければ意味がありません。通常動作中はまず問題ないでしょう。テストも万全です。しかしメニューや調整モードなどすべての処理が一定の時間内で完了する必要があります。特に気を付けなければならないのは異常系です。異常検知によるリトライ処理や異常系からの復帰処理、これらの最中にカウント値がオーバーフローすることがないよう、よく確認してください。
- 割り込み処理の中でカウント値をクリアーしない
-
割り込み処理の中でカウント値をクリアーすべきではありません。特にタイマー割り込みの中は絶対に避けるべきです。タイマー割り込みの中にクリアー処理を入れれば、ほぼ確実に一定時間毎にカウント値をクリアーできるでしょう。しかしプログラムが暴走した状態でもクリアー処理が走ってしまう恐れがあります。それでは本末転倒です。
起動時はWDTが有効であるマイコンがあります。WDTを無効にしたければ、起動直後に自ら無効に設定しなければなりません。そしてC/C++では起動時にグローバル変数を初期化します。
この2つが組み合わさった結果、予想だにしないことが起こりました。main関数が走らないのです。この原因が、大量に宣言していたグローバル変数の配列でした。試しに配列をコメントアウトすると、main関数が走り出したのです。この挙動を見て、グローバル変数の初期化中にWDTが働いたのだろうと結論付けました。対策として、大規模な配列を初期化させない設定を行い事なきを得たのです。
内部WDTと外部WDT
先に述べたとおり、WDTは殆どのマイコンに内蔵されています。しかしそれでもなお、多種多様なWDTが販売されています。それはひとえに、内蔵式WDTの信頼性の低さにあります。プログラムのフリーズがマイコンの誤作動によるものの場合、WDTそのものも停止してしまう恐れがあります。このため長時間にしろ短時間にしろフリーズが許されないシステムでは、外付けのWDTが多用されます。とはいえ内蔵式にもメリットはあります。下表を参考に内部WDTと外部WDTのどちらを選択するかを検討してみてください。
メリット | デメリット | |
---|---|---|
内部WDT | 追加コストはゼロ。 使いやすい。レジスターに特定の値を設定するだけでクリアーできることが殆ど。 途中でリミット時間を変更できる。 | マイコンの誤作動により、WDTが正常に動作しない恐れがある。 |
外部WDT | マイコンの誤作動により、WDTが無効化されることはない。 信頼性の高さこそが最大のメリット。 | 追加コストが掛かる。 マイコンの出力ポートを1本専有する。 温度の影響を受けて、オーバーフローまでの時間が変わりやすい。 マイコンがスリープなど省電力モードに入った状態でも、カウント値をクリアーし続ける必要がある。 |
WDTのタイプ
ノーマルタイプ
先に紹介したとおり、カウント値がオーバーフローするとリセットする一般的なタイプです。
ウィンドウタイプ
ノーマルタイプの一定時間経過するとリセットが掛かる機能に加えて、カウンター値のクリアー頻度が速すぎてもアンダーフローでリセットするのがウィンドウタイプです。このアンダーフローまでの、正規のクリアー信号を受け付けない期間をクローズドウィンドウ、正規のクリアー信号を受け付ける期間をオープンウィンドウと呼ぶこともあります。
コメント