回答:
まず、何が間違っているかの例をいくつか見てみましょう。
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
コメントでエドガーボネットが指摘したようstatus
に、上記のコードのようなローカル変数は、C ++コンパイラによって暗黙的に初期化されません。したがって、上記のコードの結果は不確定です。これを回避するには、必ずローカル変数に値を割り当ててください。
グローバル変数と静的変数では状況が少し異なります。
グローバル変数と静的変数は、C標準によって0に初期化されることが保証されています。
出典: AVR Libcリファレンスマニュアル-よくある質問-すべての変数を初期化すべきではありませんか?
つまり、コード内でそれらを0に初期化することについて心配する必要はありません。実際、初期化はメモリを浪費する可能性があるため、実際には回避する必要があります。0以外の値にのみ初期化します。
int array[10];
int v = array[100];
array[-100] = 10;
ここでの最初の問題は、vに何が割り当てられるのかわからないことですが、さらに悪いことに、-100の位置-100への割り当てがめちゃくちゃになることもわかりませんarray
。
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
の最初の呼び出しfuncPtr()
は、実際にはの呼び出しになりdoSomething()
ます。2番目の呼び出しは、未定義の動作につながる可能性があります。
たとえば、RAMが不足する可能性があります。ほかに何か。いずれにせよ、あなたのプログラムはおそらくあなたが意図した方法ではなく、実行し続けると思います。
コンピューターシステムでは、これらのような問題は通常、さまざまなレベルで対処されます。
Arduinosにはコンパイラの保護が限られているだけで、おそらく他には何もありません。幸いなことに、マルチタスクではないため、影響を受けるプログラムはあなただけです。いずれにせよ、これらのバグのいずれかが不安定な動作につながります。
前提は、上記のすべての問題がランタイムの問題であることです。
プログラムに実行時エラーがあるとどうなりますか?
プログラムは続行され、何が起こるかはランタイムエラーの副作用に依存します。null関数ポインターを呼び出すと、おそらくプログラムが不明な場所にジャンプします。
プログラムの実行は停止しますか?
いいえ、それは異常なことは何もなかったかのように進み続け、おそらくあなたが意図していないことをします。リセットされるか、不規則に動作する場合があります。一部の入力を出力に変換し、センサーを1つまたは2つ焼く可能性があります(ただし、これはほとんどありません)。
Arduinoにエラーを教えてもらう方法はありますか?
そうは思いません。先ほど言ったように、保護メカニズムはありません。言語からのランタイムサポート、OS、境界外のメモリアクセスに対するハードウェアチェックはありません(ブートローダーもカウントされません)。プログラムに注意するだけで、おそらく独自のセーフティネットを設定する必要があります。
保護されていない理由は、おそらくArduinoコントローラーが低すぎてメモリが少なすぎて、あまり重要なものを実行してはならないためです(はい、AVRによって、通常使用されるMCUを使用しないための免責事項があるようです)生命維持システムのArduino)。
MCUを不安定な状態から取得できるメカニズムが1つあり、それはウォッチドッグタイマーです。ループで繰り返し実行されるコードを実装している場合、それは一定の時間よりも長くは実行されない場合、この時間をウォッチドッグ期間として設定し、タイマーを有効にすることができます。
次に、ループ内のタイマーを繰り返しリセットする必要があります。終了しない条件ループでコードがフリーズすると、ウォッチドッグはゼロにカウントされ、最終的にMCUをリセットします。
この方法ではデータが失われますが、AVR WDTを割り込みモードで実行する場合、MCUをリセットする前にデータを保存できます。
そのため、ウォッチドッグタイマーは、意図しない無限ループからコードを保護できます。
ドキュメント:AVR132:拡張ウォッチドッグタイマーの使用
このようなことを行うには、ハードウェアデバッガが必要です。しかし、通常、プログラムは期待どおりに動作しないため、問題を特定するためにコードのそのセクションを確認する必要があります。
これを行うための一般的/迅速/簡単な方法は、変数またはその他の値を出力するprintステートメントを追加して、プログラムが問題なくそのポイントに到達することを確認することです。これにより、問題をさらに特定できます。
VisualMicroにはいくつかのデバッグ機能が組み込まれていると思います。