Raspberry PiはOSが動いているので、いきなり電源を切ると厄介なことになる可能性があります。私は何回か「ブッチ」していますが、とりあえずは大事故にいたっていません。しかしながら、起動時にエラーが出るなどマイナーな不具合は何度か起こっていますですので、非常時は仕方ないとして、できるだけきちんとシャットダウンしたいものです。
ここでは外部装置からの停止信号検出で止まれるように、GPIOを利用したシャットダウンスイッチを検討してみます。
まずは検索、ということで見てみるとこちらページがヒットしました。これを参考に、というか丸写しで、試してみます。ありがとうございます。
導入とテスト
このページにあるように、まずGPIOの動作を試してみます。サンプルから頂いたコードを入力します。
|
|
wait_for_edge()は割り込み動作になるので、CPU時間を消費しないはずですね。またexceptでキーボード入力をハンドルしています。
エッジを検出したあとは、つかったGPIOを掃除して終了です。
ファイルができたらchmod +x interrupt1.py
として実行できるように設定し、実行してみます。
さらに、GPIO23をGNDに落としてみます。
なにやらいろいろメッセージが出て、最終的に”Falling edge detected.”とメッセージが出れば成功。
うまく行ったら、次。
実際のコード
実際にshutdownするコードを入れますが、実際にシャットダウンしちゃうとdebugが面倒なので、とりあえずはプリント文を入れてコマンドラインから試します。
|
|
キーボード入力で停止できるように、except KeybordInterrupt
が設定されてい
ます。実際の運用では不要だとおもうので、最終的にはコメントアウトしてもいいと思います。
chmod +x shutdown-btn.py
して、実行してみます。
Dave... Dave, I don't understand why you are doing this to me...
と悲痛な叫びがコンソールに出てくればokです。
うまく動いたら、/usr/local/sbin/あたりにコピーして、最終行のコメントを外します。
一度、実際にシャットダウンできるか確かめました。そして次に。
システム起動時にスイッチ監視を始めるようにする
最後にinit.dに登録して、システム起動時にスイッチ監視を始めるように設定します。
ここはちょっと勉強が必要でした。
今回作ったスクリプトをバックグラウンドでシステム起動時に実行させたいので、initを使って起動する、と参照先のページの著者の方がおっしゃって居られましたが、いまいちその意味が自分で理解できておらず、このままではだめだなあと思い検索かけまくりましたが、イマイチすっきりしません。initからupstartが起動されて、ランレベルに応じたデーモンの起動を管理する。という感じではあるのですが。。。
ま、ここら辺は後から補完するとして、とりあえず深く考えずやってみます。
/etc/init.d/ の下に下記のようなスクリプトを作成します。
|
|
スケルトン(/etc/init.d/skeleton)からINIT INFOのあたりをコピーして、その下は先のwebページのものをコピーです。
init.dのスクリプトの書き方は、ここらへんが詳しいですが、英語です。
コメント行も重要のようです。ちょっと見てみると
|
|
start-stop-daemon についてはmanを見るのが一番わかりやすいかもしれません。よく分かっているわけでは無いので詳しくは書けませんが、要はシステムレベルのプロセスの管理に便利だ、と言うことでしょうか。(そうmanに書いてあるし)
ちなみに、ここでのオプションを確認しておくと
- -S プロセスをスタートをさせる。
- -x /usr/local/sbin/shutdown-btn.pyは -Sオプションの引数で、-xで指定された実行ファイルのインスタンスであるプロセスがあるかどうか、を返します。
この2つで、指定した実行ファイルがプロセスとして起動していればそのまま、起動していなければ起動されます。
- -b バックグラウンドに移行
- -m star-stop-daemon用のPIDファイルを-p で指定したファイル名に従って作成します。
これちょっと、オプションがいっぱいあってわかりにくいので、オプションをフルスペルとかにしたほうが可読性が良い感じですね。
ちなみに、上のやつをわかりやすく書き直すと
|
|
てなかんじでしょうか。動作確認していないのでご注意ください。
起動用のスクリプトが編集できたら、これを登録します。
これで、defaultのランレベル設定で当該のスクリプトのシンボリックリンクが/etc/rc?.dのディレクトリに作成されます。
これで、起動時にこのスクリプトがスタートするようになるはずです。
再起動と動作確認
ここまで来たら再起動させてみます。これでリセット用のGPIOの監視プロセスが起動されているはずです。
そして、GPIO23をGNDに落としてみます。
見事シャットダウンされました!
めでたし。
今回、init.dの使い方もちょっぴり勉強出来ました。
#####2015/2/11 追記:
#####システム組み込み用としては、シャットダウンしたあとに自動で電源を切るような回路がほしいところです。
#####このとき問題なのは、どの時点で電源を切ればいいかということです。システムはダウンしてしまっているので、ソフトウエアは関与できません。システムが終了したら状態が変化するどこかの端子の電圧をモニタして、そこが変化したら切る、というような事をしないといけません。さてどこを見ればいいか。