Arduinoを常に動作状態に保つ方法についてです。 ウォッチドッグメカニズムはAtmegaコントローラーに組み込まれていますが、残念ながら、すべてのArduinoブートローダーがこの機能を正しく処理するわけではありません。 この問題に対処してみましょう。
ウォッチドッグとは何ですか? 簡単に言えば、これは特定の時間(チップに応じて最大8秒)の組み込みタイマーであり、プログラムで実行できます。 タイマーがゼロに「下がる」とすぐに、コントローラーは正しいリセット信号(RESET)を出し、デバイス全体がハードリセットになります。 最も重要なことは、このタイマーをプログラムで初期状態にリセットすることもできます。
- 正しいリセット信号は、コントローラーが過負荷を開始するのに十分な長さです。 Arduinoデジタル出力をRST入力に接続し、再起動する必要があるときに0に設定したい場合があります。 これは問題を解決するための悪いアプローチです。なぜなら、 そのような信号は時間内に十分ではないかもしれませんが、場合によってはこれも機能する可能性があります
- ハードリブートは、リセットボタンを押したときに発生する実際のリブートです。 実際には、ソフトリセットの概念もあります。これは、0番目のアドレスへのプログラム遷移です。 原則として、これも有用なものですが、その助けを借りて、ハングしたイーサネットコントローラーまたは使用されていないLCDを再起動することはできません。
要するに、組み込みのウォッチドッグは、追加の回路、はんだ付け、接続なしで必要なものです。
ウォッチドッグ機能
ウォッチドッグ機能を使用するには、標準ライブラリをプロジェクトに接続する必要があります。
#include <avr/wdt.h>
現在、次の3つの機能を使用できます。
1.ウォッチドッグタイマーの開始:
wdt_enable(WDTO_8S); /* WDTO_15MS WDTO_30MS WDTO_60MS WDTO_120MS WDTO_250MS WDTO_500MS WDTO_1S WDTO_2S WDTO_4S WDTO_8S */
タイマーは、定数で指定されたとおりにカウントします。 この時間が経過すると、再起動が行われます。
2.ウォッチドッグタイマーをリセットします。
wdt_reset();
この関数が必要な理由は理解できると思います-あなたがそれを呼び出すまで、コントローラーはリセットされません。 システムがフリーズし、この関数が呼び出されなくなるとすぐに、指定された期間の後、リブートが発生します。
3.ウォッチドッグを無効にします。
wdt_disable();
ウォッチドッグタイマーを無効にします。
実際、これでウォッチドッグについての話を終わらせることができます...しかし、事実は、これらはすべてArduino Unoでのみ動作し、Arduino Mega、Mini、Nanoではまったく逆に動作するということです。 まったく動作しません:)
ウォッチドッグが最新のArduinoボードで機能しない理由
実際には、ウォッチドッグによって引き起こされた再起動後、最新リリースのコントローラーは最短期間ウォッチドッグをオンのままにします。 15ms。 これは、前回の再起動がウォッチドッグによるものであることをプログラムが何らかの形で検出するために必要です。 したがって、ローダー(または、最初に起動する場合はプログラム)の最初のタスクは、再起動が「予期しない」情報を保存し、すぐにウォッチドッグをオフにすることです。 これが行われない場合、システムはブートループに進みます。 永遠に過負荷になります。
ご存じのとおり、Arduinoには、主にシステムの再起動後に実行される特別なブートローダーがあります。 そして、残念ながら、標準のブートローダーはウォッチドッグをリセットしません! したがって、システムは残酷なブートループに入ります(13番ピンのLEDがクレイジーに点滅する「クレイジーLED」状態)。
すべて次のようになります。
問題を解決する方法
標準のブートローダー(プラットフォームに付属)のソースを見ると、ウォッチドッグ切断コードは(!)ですが、このコードは条件付きでコンパイルされており、ほとんどの場合、標準のブートローダーはウォッチドッグのサポートなしでコンパイルされています。 少なくともプラットフォームパッケージバージョン1.5.2(執筆時点では最後)では、これが事実です。
問題を解決するために、私はプラットフォームの人(:)を読みましたが、この問題はそこに記述されており、誰もが幸せになるようなコードさえ与えられているようです:
uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3"))); void get_mcusr(void){ mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); }
ここではget_mcusr()関数について説明します。これはリセット直後に呼び出す必要があります。 これは、マクロ "__attribute __((section("。Init3 ")))によって実現されます。 私はこの関数を可能なすべてのセクションに書き込もうとしました-はい、実際にはスケッチからセットアップ()関数の前に開始されますが、残念ながらリセット後15ms(最小ウォッチドッグ定数)よりはるかに遅く...
つまり、問題を簡単に解決する方法を探してインターネットを掘り下げたとしても、何も見つかりませんでした。 ウォッチドッグを動作させる方法は1つしか見つかりませんでした。ブートローダーを再フラッシュすることです...これは今から行います。
ウォッチドッグのパフォーマンスの確認
何かをフラッシュする前に、確認する必要があります-突然、Arduinoはウォッチドッグをサポートします。 このために、テスト用の小さなスケッチを書きました。 記入して、ポートモニターを開き、何が起こるかを確認します。
ウォッチドッグでのテスト
#include <avr/wdt.h> void setup() { wdt_disable(); // bootloop Serial.begin(9600); Serial.println("Setup.."); Serial.println("Wait 5 sec.."); delay(5000); // , bootloop wdt_enable (WDTO_8S); // 8 . Serial.println("Watchdog enabled."); } int timer = 0; void loop(){ // Serial if(!(millis()%1000)){ timer++; Serial.println(timer); digitalWrite(13, digitalRead(13)==1?0:1); delay(1); } // wdt_reset(); }
再起動後(またはモニターをポートに接続した後)、内蔵LEDが点滅し、ブートローダーが開始されたことを示します。 次に、セットアップセクションで、ウォッチドッグが8秒間タイマーでオンになります。 その後、今回はLEDがカウントされ、再起動が行われます。
次に、楽しい部分が始まります。再起動が発生し、すべてが同じシーケンスで繰り返される場合、Arduinoが手元にあり、ブートローダーがウォッチドッグを正しく処理します。 再起動後、13番目のピンのLEDが無限に点滅し始めた場合、ブートローダーはウォッチドッグをサポートしていません。 ここでは、リセットボタンも役に立ちません。 それ以降のファームウェアでは、ボードを電源から切断し、電源を入れた後、最初の再起動前にフラッシュする時間を確保する必要があります。
4種類のボードをテストしましたが、Arduino Unoのブートローダーのみが正常に機能しました。
結果を監視する
ウォッチドッグはブートローダーでサポートされていません。
| ウォッチドッグは、ブートローダーによってサポートされています。
|
新しいブートローダーをフラッシュする最も簡単な方法は何ですか?
別のプログラマーを使用してArduinoでブートローダーをフラッシュするか、同じArduinoを使用して独自のプログラマーを構築できます。 つまり Arduino ボードはすべてプログラマーになり、特別なスケッチを記入できます。
この記事では、Arduinoベースのプログラマーを作成するすべての知恵について説明しません。 このトピックは、インターネット上で詳細に説明されています 。 プログラマーとして、私はArduino Unoを使用しました。 ご存知のように、ファームウェアは、ほぼすべてのボードにある個別のICSPコネクタを介して生成されます。 ICSPを持たないファームウェアArduino Pro Miniの場合、結論に直接接続されます。
ブートローダーファームウェアの接続
ウォッチドッグをサポートするブートローダーはどこで入手できますか?
この章はタンバリンとのダンスを連想させるもので、おそらくすべてを何らかの形でシンプルにすることができますが、残念ながら、私は別の方法で管理しませんでした。
optibootパッケージのブートローダーを使用することをお勧めします。 原則として、これらのブートローダーはArduinoプラットフォーム自体のインストールに使用されますが、 ここから optibootの最新バージョンをダウンロードしてインストールすることをお勧めします 。 インストールは2つのステップで構成されます(おそらくこれは何らかの方法で実行できます)。
- ブートローダー\ optibootフォルダーはCで上書きされます:\ Program Files(x86)\ Arduino \ hardware \ arduino \ avr \ bootloaders \ optiboot
- board.txtファイルは、ファイルCに追加されます:\ Program Files(x86)\ Arduino \ hardware \ arduino \ avr \ boards.txt
当然、Arduinoプラットフォームのインストールフォルダは異なる場合があります。
次に、開発環境が過負荷になり、[サービス/ボード]メニューで[optiboot]とマークされた新しいボードを確認できます。 残念ながら、これらのボードを選択すると、いくつかの奇妙なコンパイルエラーが発生し、他のあらゆる種類の奇妙なものが表示されます。 ファイルC:\ Program Files(x86)\ Arduino \ hardware \ arduino \ avr \ boards.txtをテキストエディターで開き、次の行を変更します。
Arduino Nanoの場合:
menu.cpu.nano.atmega328.bootloader.file = optiboot / optiboot_atmega328.hex
Arduino Miniの場合:
menu.cpu.mini.atmega328.bootloader.file = optiboot / optiboot_atmega328.hex
次の問題は、Arduino Megaボード用のoptibootブートローダーが自然界に存在しないことです。 Megaはより多くのメモリを持ち、異なるプロトコルを使用します。 そのため、標準の、ただし変更されたブートローダーを使用します 。これはここからダウンロードします 。 ファイルの名前をstk500boot_v2_mega2560_2.hexに変更し、フォルダーC:\ Program Files(x86)\ Arduino \ hardware \ arduino \ avr \ bootloaders \ stk500v2に書き込みます。
次に、すでに馴染みのboards.txtファイルの次の行を変更します。
mega2560.bootloader.file = stk500v2 / stk500boot_v2_mega2560_2.hex
Mega用に変更されたファームウェアのファイルは、標準の2倍小さいことを心配しないでください。
ファームウェアプロセス
すべての変更の後、ボードメニューで([optiboot]ではなく!)通常のボードを選択して、ブートローダーをフラッシュできます。 この場合、フラッシュされるのはboard.txtファイルで指定した16進ファイルです。
ファームウェアプロセスが開始されず、エラーが発行される場合があります。
avrdude: stk500_getsync(): not in sync: resp=0x00
この問題を解決するには、プログラマスケッチを開き、セットアップセクションで別のシリアルポート速度を選択します。
Arduino Megaを注ぐ際に、無視すべきエラーが表示される場合があります。
avrdude: verification error, first mismatch at byte 0x3e000 0x0d != 0xff avrdude: verification error; content mismatch
最終的な操作
optibootブートローダーには別の機能があります-スケッチの読み込み速度が向上するため、optibootでボードを使用する場合は、boards.txtに適切な変更を加える必要があります。
Arduino Nanoの場合:
menu.cpu.nano.atmega328.upload.speed = 115200
Arduino Miniの場合:
menu.cpu.mini.atmega328.upload.speed = 115200
以前のポート速度も覚えておくとよいでしょう。なぜなら、 標準のブートローダーを搭載したボードで使用する必要があります。 このような変更を行わないと、スケッチプロセス中に次のようなエラーが生成されます。
avrdude: stk500_getsync(): not in sync: resp=0x00
参考文献、文献
Optibootパッケージ
ブートローダーファームウェア
Arduino Pro Miniでブートローダーをフラッシュする方法