ラズベリーパイのハードウェアWDT   
                                               2024年 1月
【ラズパイがハングアップする】
 ラズベリーパイを長期間、連続運用していると、電源は入っているのに全く応答しなくなる事があります。こうなると電源を落とすしか方法がなく、一旦電源を落とし、再度投入すると普通に動作を開始します。近くで運用している時は良いのですが、離れたところで運用している場合は、全くの困りものです。
 一般的にマイコンにはWDT(Watchdog Timer)という機構があり、何らかの原因で暴走した場合にはそのことを検知して再起動するという仕組みが備わっています。もちろんそれを適用しないと働きませんが ・・・。 それでラズベリーパイにも、その仕組があるはずだと思いネットでの検索をしました。有りました、 ここに 詳しく解説されています。ありがとうございます。さっそくこれを参照させていただいて設定しました。その中に解説されているように、動作確認のための「フォークボム(Fork爆弾)」を撃ってみますと、確かに再起動します。
 よ〜し、これで一安心と思い一ヶ月ほど運用したところ、またハングアップが起きてしまいました。う〜ん、これは何なんでしょう??? 電源の容量も不足ではないようですし、理由はわかりません。ただハッキリしていることは、たとえこれが発生した場合であっても、「一旦電源を落とし、再度投入する」を行えば、復調して再び長期にわたって運用することはできているということです。面倒な事ですが、実はこれを「遠隔地ビデオモニター」について、一年半ほど実行していました、しかしさすがに根負けしそうになりました(笑い)。
 そこで、ラズベリーパイが持っている WDT だけに頼らない、別のやり方の
追加を考えて見ました。つまりラズベリーパイのあるポート(GPIO)に「パルスを一定周期で出力」するソフトをラズベリーパイの側に入れて常時起動して置き、そのパルスをこれから追加する外部の基板で監視して、検出できなくなったら、その基板でラズベリーパイの電源を落とし、しばらく時間をおいて電源を再投入するという、これまで手作業でやってきたことを代わって実行してくれる小基板を作製してみることにしました。以下は、その報告です。現在のところ、上記しましたラズベリーパイ自身によるものと、この外部基板との二重の対策になっていますが、とてもウマク動作し、安定して運用できています。
 この実装済(マイコン書込み済)の基板がご入用でしたら、「Raspberry Pi ハードウェア WDT 基板」とご記入の上、汎用製品通販のページのトップのメールアドレスへお申込みください。なお、パルス発生の監視とともに、ラズパイ側からある間隔でルーターへの ping テストを行い、ネットワークが不調になった場合の監視の一部も、
追加いたしております。これも結構、有効なようです。

[ Contents ]
1. 小基板の回路と実装図
2. 小基板のファームウェア
3. フローチャート
4. ラズベリーパイ側のソフトと設定
. 動作確認
  Appendix (GPIOの入力の表示)
  運用例 (一年間を通して)の報告


1. 小基板の回路と実装図
 マイコンは、マイクロチップのPIC12F1612を搭載しています。電源は、ラズベリーパイの電源入力と同サイズのマイクロUSBのコネクタを付けていますので、それまでラズベリーパイに供給していたものをこの基板にさしてください。ラズベリーパイの電源は、この基板を通して、GPIOの2, 4番ピン(+5V)、6, 9, 14番ピン(GND)から供給します。ですから、
ラズベリーパイの元の電源は未接続にします。(ただし、ラズパイ4には、USB-C(メス) → microUSB(オス) 変換 アダプターが必要、Amazonや楽天・他で安価に入手できます)
 CN1 と CN2 は基板の裏に付いている
メスのコネクタですから、ラズベリーパイのGPIOピンの1〜16ピンに刺さります。つまり、ここから電源はラズベリーパイに供給れます。CN3 と CN4 は基板の表にオスのコネクタで実装されており、CN1 と CN2 にパラに接続されていますので、ラズベリーパイの1〜16ピンの代替になります。なお、どの GPIO からラズベリーパイの監視用パルスを入力するかを S1〜S5 で選択しますので、半田でショートしてください。ここでは、S3 の IO22(15番ピン) を使用しています。なお、この小基板は、ラズベリーパイの外側に取り付ける様に設計しています。もし直接、ラズパイに取り付けることがケースなどで難しい場合は、+5V, GND, パルス入力 の3本だけをリード線で出して、ラズベリーパイのコネクタの該当位置に接続することでも良いです(写真を参照)。回路図をクリックすると大きめに表示されます。なお部品の品番は変わることが有ります。



  実装図(サイズ48x23mm)


2. 小基板のファームウェア
 マイクロチップ様の MPLAB-X-IDE において CCS-C でコンパイルしています。タイマーは、SMT1 のタイマーモードを使っており、内容的にはシンプルですので、マイクロチップ様のコンパイラ(XC8)にもすぐに移植できると思います。リストは以下の通りです。

リスト RaspPi_Wdt7


下図が、プロジェクトの様子です。コンパイルして書き込んでください。こちらの基板を使えば CN-PRG から書き込むことができます。




3. フローチャート
 上の PIC のファームウェアのフローチャートを下図に示します。@ 「電源投入から、ラズベリーパイが送っているパルスの初期検出」の部分。次に A 「常時の運用中のパルスの送出を検証」する 部分。最後に B 「パルスが検出できなくなった時に電源を切断」する 部分の3つのパートから構成されています。@->A->B->@->A のようにループします。ラズベリーパイにパルスを送出するソフトを組み込んでいない場合は、最初の@の中でループしますので、電源は入ったままとなり、そのままラズベリーパイは通常通り使用できます。

 ここでは、パルスは 0.5秒ON、0.5秒OFF の連続を想定しています。この ON/OFF が5秒以内に来ないと電源OFF のモードに入りますから、それに間に合うようにラズベリーパイからパルスを送出するようにしてください。
また、パルス幅は関数 int ChkInPin(int32 BIT, short OFON) の中で、20ms 以上と設定していますのでそのようにして下さい。もし変更が必要であれば、ソースから変更してください。なお、AからBに移る際に60秒のタイマーを挿入した RaspPi_Wdt8 も提供致しております。これを利用して、電源断の前に、データの退避やその他の処理をする方もおられます。その場合は、御注文の際に「RaspPi_Wdt8 を使用」の旨を指定して頂きますと対応いたします。指定がなければ、このフローチャート通りの RaspPi_Wdt7 を書き込んで出荷いたします。


4. ラズベリーパイ側のソフトと設定
 GPIOに連続パルスを出力する Python によるサンプルを示します。この中には、今回のパルス発生以外に、SWでシャットダウンするための部分もいれていますが、不要であれば削除してください。これは元々SWでラズベリーパイをシャットダウンするために作成していたものに、今回の
連続パルス出力部を追加したものです。
 シャットダウンSWは GPIO17(Pin11:ここがHighになるとAvtiveになる)に、パルス出力は GPIO22(Pin15) に割り当てています。コードを見ていただければ分かると思いますが、パルスは 0.5秒 ON/ 0.5秒OFFの繰り返しであり、ほとんどは sleep(0.5) の実行ですので、他の処理の支障になることはないと思います。(なお、ネットワーク監視の項目の追加をしています、下に記入している
追加しました
を御参照ください)
注意!:文字コードは UTF-8 で保存しなければラズパイで動かす時にエラーとなります。
      ラズパイ側のテキストファイルは UTF-8 でなければなりません。

リスト shutdown_Wdt.py


この shutdown_Wdt.py を
ラズベリーパイ 起動時に稼働するように /etc/rc.local ファイルに記述してください。
ここでは nanoエディタで以下のように起動しています。
sudo nano /etc/rc.local

23行がそのパルス送出・シャットダウン操作のための設定です。
21, 22行は、その他の設定のサンプルですので、必要な設定に書き換えてください。
内容は同じではないと思いますが、要するに exit 0 の前に
「python /home/pi/shutdown_Wdt.py &」 が記述されていれば良いです。もちろんこの場合は、shutdown_Wdt.py は /home/pi の場所に 保存してください。場所は任意ですのでご自分の好きな場所で良いです。


1 #!/bin/sh -e
2 #
3 # rc.local
4 #
5 # This script is executed at the end of each multiuser runlevel.
6 # Make sure that the script will "exit 0" on success or any other
7 # value on error.
8 #
9 # In order to enable or disable this script just change the execution
10 # bits.
11 #
12 # By default this script does nothing.
13
14 # Print the IP address
15 _IP=$(hostname -I) || true
16 if [ "$_IP" ]; then
17 printf "My IP address is %s\n" "$_IP"
18 fi
19
20 # for Start file
21 sudo systemctl start webiopi
22 sh /home/pi/xxxxxx-stream.sh
23
python /home/pi/shutdown_Wdt.py &
24
25 exit 0

下の図は、ラズベリーパイが送出している信号 (GPIO Pin15) を観測したものです。上の rc.local に登録している shutdown_Wdt.py の記述に、もしミスがあってもエラーは表示されません。ですからエラーがあればパルスは発生しませんが、それに気が付かない事があります。キチンとエラー無しで起動されているかは、このパルスの発生で確認できますので、下に記述しています
基板の動作確認をされることをお勧めします。

 ラズベリーパイからの信号

【 追加しました
 ラズパイに支障が起こった時の症状は色々とあると思います。メインのアプリケーションの動作がおかしくなっても、ラズパイ固有のWDTに引っかかることもなかったり、この監視用のパルスの発生にも問題なかったりすることもあると思われます。それで、
チェック項目の追加をしました。
 それは、自分のルーター(192.168.1.1) に ping を打って、"1 received" という応答が含まれているかを 10分間に1回実行し、全トライ5回の内に1回でも返ってくれば何もしない、もし返らなければ shwfg フラグを 1 として、監視用のパルスの発生を停止する、という処理を入れました。これで重要項目であるネットワークの監視の一部もできると思います。もちろんこの項目は、ネットワークを使っている場合のみですので、
使っていない場合は、cnt += 1 をレム(頭に#を記入)にしてください。また、私のルーターのアドレスは、192.168.1.1 ですが、これはそれぞれ違うと思いますので、shutdown_Wdt.py の以下の行 ・・・
cmd = 'ping 192.168.1.1 -c 1'  #ルーターにping
・・・ これに含まれるルーターのアドレスをお使いのアドレスに変更してください。実際のテストは、ラズパイのターミナルより、下図のようにテストして、ご自分のルーターアドレスを確認してください。"1 received"が含まれていれば良いことになります。




5. 動作確認
 下の写真は運用している例です、こちらでは実際には、カメラ(ラズパイ標準) 付きの遠隔地ビデオモニターに取り付けています。下図はテストのための構成です。左の方は、コネクタが挿せる状態の時で、この場合は別途配線は必要ありません。右の方は、ケースの構造で直接コネクタを挿せない時の例で、その場合は電源(+5V, GND) とラズベリーパイから受け取る信号の線の3本を接続して下さい。ラズベリーパイの GPIO の初めの 16ピンと、この基板の 16ピンは同じ配列ですので、ケース構造で挿すことができる場合は左のようにそのまま挿せます。挿せない場合は、右の写真のように、赤(+5V) は 4番ピン、茶(GND) は 6番ピン、橙(信号) は 15番ピンに接続しています。配線は、できるだけ太く・短い方が良いです。
ラズパイが壊れますので、ショートしたり逆さしになったり、ピンずれが起きないように十分に御注意ください。
 ラズベリーパイが立ち上がって動作している時に、右の接続をしていれば、橙色の線(信号)を外すと信号が検出できない状態となり、約5秒後に小基板の LED が点灯してラズパイの電源がOFF となります。それから約30秒間 OFF が続き、その後再起動のため電源ON となり LED は OFF となります。これで、この
基板の動作確認ができます。4.(上記)の「ラズベリーパイ側のソフトと設定」をしていない場合は、フローチャートの@で待機になるので電源は入ったままとなり、普通にラズベリーパイはそのまま使用できます。
ラズベリーパイの
GPIOピン配置は、こちらなどを御参照ください。各機種、1〜16ピンは共通になっています。



 これをラズベリーパイに取り付けることによって遠隔地に設置している ビデオモニター(ラズパイ標準カメラ付き) を安定して稼働させることができるようになりました。結局、
最初に述べた対策もそのまま使っていますので、二重の対策をしていることになります。

追記
 遠隔地ビデオモニターとは別に、「Raspberry Pi Zero WH」を使って連続でインターネットラジオを再生しているのですが、それがハングアップしました。これにはもちろん最初に述べたラズベリーパイが持っている対策を入れており、「フォークボム(Fork爆弾)」での確認もとっておりました。まったく音が出なくなっていたので「リモートデスクトップ」の接続を試みましたが、これも接続できませんし、ping も通りません。それでも電源を入れ直しましたら問題なく動作を再開しました。ラズベリーパイが立ち上がり、ラジオが再生された時に、再確認のため、もう一度フォークボム(
:(){ :|:& };:)を撃つとキチンと再起動します。そういうことなので、遠隔地ではないのですが、このインターネットラジオにも、このWDT基板を取り付けることにいたしました。

【Appendix】

 この WDT基板には以下の追加は、ハードウェアとしては対応していませんが、実は PIC の 7番ピンに Reportの出力(この基板が再起動を実行したことを示す)を On/Off で示すようにしています。この PIC のポートに負荷抵抗と LED を追加すれば、この基板がラズパイの再起動を実行した時は LED が点滅します。また、6番ピンを入力(内蔵PullUpしている)にしており、ここを GND に落とせば RS232C(19200bps:6番ピン, TX)で、その再起動を実行した回数を見ることもできるようにしています。上記のファームウェアに、これらは既に入れておりますが、これらを使わなくても基本の動作には全く影響はないです。
 さらに、7番ピン(Report)の出力(5V-GND)を、そのままでは電源レベルが違うため直接には GPIOに入れられないため、 7Pin-10KΩ-20KΩ-GND を接続し、抵抗の中点を
GPIO(INに設定)に入れ、この入力の状況をブラウザに表示するようにすれば、その入力の点滅により、遠隔地よりラズベリーパイの再起動があったかどうかを知ることができるわけです。GPIO(OUT) をブラウザから操作する方法についてはネット上に多くの例があるのですが、GPIO(IN) の入力をブラウザに表示する方法について、WebIOPi が提供している関数のみで行っている例が見つからず手間取りました。
 WebIOPi 提供先のメインメニューの GPIO Header (http://192.168.x.xx:8000/app/gpio-header) では表示されているので方法はあるはずです。試行錯誤の結果、以下の方法でブラウザの画面に表示できるようになりました。要は、
OUT も IN も同じ Button を使っており、OUT に設定するか IN に設定するかでその動作が変わってくるということです。IN に設定した場合の表示は、ポートの High/Low を反映し、クリックは無視されます。また、入力をボタンに表示できるようになった当初、入力(GPIO) を High/Low しても表示は変化しなかったのですが、それに IOPI.refreshGPIO(true); を追加することで変化・応答するようになりました。
実際のビデオモニターの表示に使っている index.html を下記に示します。

リスト index.html


下図の写真は、実際に使っている遠隔地ビデオモニターの例 (一部のみ表示) で、皆様の環境とは違うと思いますが、
要はWebIOPiを使っている以下の記述に注目してください。
;--- Java Script ---
IOPI.setFunction(25, "IN");
var WarnBtn = IOPI.createGPIOButton(25, "報告");
$("#warnbtn").append(WarnBtn);
IOPI.refreshGPIO(true);
;--- Body ブロック ---
<div id="warnbtn"></div>

ブラウザ表示の例 (一部)


 この「遠隔地ビデオモニター」は、金丸隆志氏の「実例で学ぶ Raspberry Pi 電子工作」の第6章を使用させていただいております。オリジナルのコードに、ボタン操作・表示部(報告)を追加いたしました。さらに、外部のネットワークからアクセスできるように、「MyDNS」に登録し、グローバルアドレスを取得(ありがとうございます)し、遠隔地からモニターできるようにいたしました。これは後閑哲也氏の「PICと楽しむRaspberry Pi」の第7章を参照させていただきました。
 上図の表示の「照明」が OUT で、現在の表示は点灯している状態です。「報告」は IN で、現在は Low の状態です。なお照明には、商用電源(AC100V)を使っており、秋月電子通商さんの
ソリッド・ステート・リレーキットを使って室内の照明を On/Off しています。

【 運用例 】
 最後に、どれくらいの期間でこのハードウェアWDT による再起動が起こっているかを、実際の運用例からご報告します。この
「遠隔地ビデオモニター」で使っているものは「Raspberry Pi 2 Model B」です。これまでも、何回かハングアップは経験していますが、その間隔は、1〜6ヶ月など様々でした。このハードウェアWDT でのテストは、2020年1月20日にセッティングして、4月10日に「報告」の項目が点滅を開始しました。ですので約80日間の運用で再起動が確認された事になります。そのまま運用してもビデオモニターは正常に動作しているので全く支障はないのですが、次の日に現場に行く用件がありましたので、「報告」をクリアして、次の再起動を確認できるようにするために再セットしました。また、再起動が起こりましたら追加の報告をします。再起動の間隔は、様々な状況によって変わるとは思いますが1つの参考になれば幸いです。

【 追加の報告 】
 2回目の再起動は、2020年4月11日にセッティングして、8月19日に「報告」が点滅を開始しました。この場合、
130日間の運用でハードウェアWDT による再起動が起こったことになります。
 3回目については、2020年8月20日にセッティングして、12月7日に「報告」が点滅を開始しました。したがって、
109日間の運用でハードウェアWDT による再起動が起こりました。もちろん、再起動後のビデオモニターは正常に動作しています。つまり、一年間におおかた、3回の再起動があったことになります。
この間隔は、ハードウェアWDT を取り付ける前に体験しているハングアップ状況と、ほぼ同じような振る舞いだと感じています。
結論としてこれらの対策を実施してからは、一年間を通して「遠隔地ビデオモニター」は、実質上のハングアップなしで稼働し続けたことになります。

 なお、「遠隔地ビデオモニター」をもう一式、稼働しており、これにもこのハードウェアWDT を取り付けています。構成は、「Raspberry Pi 4 Model B」により、USB カメラを使っています。これもほぼ一年間ほど、連続の運用をしていますが、実質上のハングアップはせずに稼働し続けています (観察の報告: 一時、ビデオモニターが不能になり、パソコンからラズパイ宛に ping を打っても応答しない状況になったことが確認されました。しかし、この状況なら
上記の対策 などにより回復するだろうと思いました。その後、しばらく放っていたら回復し、モニターできるようになりました)。

2022,4,12 時点の総括報告
上記の「Paspberry Pi 2 Model B」と「Raspberry Pi 4 Model B」による「遠隔地ビデオモニター」、それに 「Raspberry Pi Zero WH」による「インターネットラジオ」および「温度計測とWEB表示」は、いずれも 実質上のハングアップをせずに稼働し続けています。

;------------------------------------------------------------
(別途の報告)
 先に「インターネットラジオ」を再生していて、それにもこのハードウェアWDT を取り付けていることを述べました。この「遠隔地ビデオモニター」と同等の対策をしているのですが、過去(2021年)、約一年間の運用で、音が出なくなりました。しかし、システム自体は、ハングアップはしていませんでした、というのは、リモートデスクトップは繋がるのです。それでリモートを使って調査すると、新手の原因であることが分かり、そのための対策を追加しました。対象のアプリケーションの動作がオカシクなっても、ラズパイが元々持っているWDTにも引っ掛らず、「ハードウェアWDT」のチェック用のパルスを停止することもないことが、このようにあるのですね。このような場合は、それに対応する上記のような対策を追加することが必要になると思います。
つまり、システム自体がハングアップしなければ、このように
リモートで原因の調査と対策をすることが可能になります。
2022,5,7 有料(約1円/日)になったため、聴取を停止しました。しかし、約一年後に稼働したところ聴取できるようになっていました。


Reported by TokioYamada@ADK            Topへ


汎用製品通販のページへ    ラズパイ Zero によるインターネットラジオへ    USB-IOのページへ