LoginSignup
9
4

More than 3 years have passed since last update.

第15回 Raspberry Pi で監視カメラを作ろう! ~アプリの自動起動編~

Last updated at Posted at 2019-08-26

Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成するシリーズ記事です。
本記事はリンク情報システム株式会社の有志が作成しています。


Raspberry Piの起動と共に監視カメラ映像配信アプリを自動で開始できるようにします。

アプリの自動起動

今回使用しているOSはRaspbianというdebianベースのLinuxです。
Linuxで一般的に自動で起動するアプリケーションの事をデーモンと呼びます。
そこで、監視カメラ映像配信アプリをデーモンに改造し、自動起動できるようにします。

デーモンの作成や起動/停止について、銀の弾丸さんの記事を参考にさせて頂きました。
参考元:ラズパイで自動起動するデーモンを自作する - 銀の弾丸

デーモン作成

デーモン作成の流れは以下のようになります。
 1.デーモンプロセスの生成
 2.ログ(syslog)の出力
 3.プロセスIDをファイルへ保存
 4.SIGTERMで終了

参考記事に紹介されているdaeomonize.c を元に、ポイントとなる実際の処理を抜粋して解説します。

1.デーモンプロセスの生成 (daemonize関数)

Linuxに用意されている、デーモンを生成するためのdaemonという関数を実行します。
daemon関数を実行したプロセスはforkしてから終了するそうなので、daemon関数を実行した時点でプログラムがデーモンに変化した事になります。

if (daemon(0, 0) != -1) {
2.ログ(syslog)の出力 (daemonize関数)

デーモンはターミナルとは切り離されているため、ユーザーと直接対話する事ができません。そのため、エラー発生や動作状態等の情報はログ(syslog)に出力することになります。

/* syslog_ident, = "redbrick" */
/* syslog_option = LOG_PID */
/* syslog_facility = LOG_DAEMON */
openlog(syslog_ident, syslog_option, syslog_facility);
3.プロセスIDをファイルへ保存 (daemonize関数)

起動や停止する対象(デーモン)を特定するためにプロセスIDを使用します。そのため、ファイルにプロセスIDを出力しておきます。

if(pidfilepath) {
  FILE* pidfile = fopen(pidfilepath, "w+");
  if (pidfile) {
    int pid = getpid();
    fprintf(pidfile, "%d\n", pid);
    fclose(pidfile);
  } else {
    syslog(LOG_ERR,
      "daemonize() : failed to write pid.\n");
  }
}

4.SIGTERMで終了

デーモン終了時は、SIGTERMが送信されます。
ですので、デーモン形式のプログラムは、SIGTERMを受け取る準備を行ってから、目的の処理を行い、SIGTERMを受け取った時点で、処理を終了するようにします。

static int terminate = 0;
static void signal_handler(int signal_number)
{
   terminate = 1;
}

static int MainLoop()
{
    signal(SIGTERM, signal_handler); 
    while(terminate == 0)
    {
        // 何らかの処理を行う
        sleep(1);
    }
    signal(SIGTERM, NULL);
}

デーモン起動/停止スクリプト作成

デーモンの起動/停止を行う為には、スクリプトを用意する必要があります。
スケルトン(/etc/init.d/skeleton)をコピーしてデーモン起動/停止スクリプト(/etc/init.d/redbrick)を作成します。

#!/bin/sh
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
    set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides:          redbrick
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.  This example start a
#                    single forking daemon capable of writing a pid
#                    file.  To get other behavoirs, implemend
#                    do_start(), do_stop() or other functions to
#                    override the defaults in /lib/init/init-d-script.
### END INIT INFO

DESC="RedBrick Onvif Camera service"
NAME=redbrick
DAEMON=/usr/bin/redbrick
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

「# Provides」、「DESC」、「NAME」を監視カメラ映像配信アプリの名称に書き換えます。
「DAEMON」には監視カメラ映像配信アプリのパスを設定します。
「DAEMON_ARGS」はパラメータを設定しますが、監視カメラ映像配信アプリには不要なので、空文字にします。
「PIDFILE」はプロセスIDを保存したファイル名を設定します。
「SCRIPTNAME」は編集しているデーモン起動/停止スクリプトファイル名が設定されていれば、変更の必要はありません。

自動起動の登録

スクリプトが完成したら、insservコマンドで自動起動の設定を登録します。

$ sudo insserv redbrick

自動起動が登録されると各ランレベルのディレクトリにスクリプトのシンボリックリンクが作成されます。
lsコマンドなどでリンクが作成されていることを確認してください。

$ ls -l /etc/rc3.d/
S03redbrick

"S~" が作成されている場合は、自動起動の対象となっている事を意味します。
自動起動が無効になっていると"K~" となります。

自動起動の確認

rebootコマンドで再起動すれば、自動起動します。
起動できているかは、statusコマンドで確認できます。

$ sudo /etc/init.d/redbrick status
[ ok ] redbrick is running.

インデックス記事へ
第14回記事へ
第16回記事へ


リンク情報システム株式会社では一緒に働く仲間を随時募集しています!
また、お仕事のご依頼、ビジネスパートナー様も募集しております。お気軽にご連絡ください。
 
 

9
4
13

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4