Raspberry Pi 用の Real-Time Clock (RTC) モジュールを導入してみた@CentOS7

別に NTP があれば要らないじゃない?と言われそうだけど、Raspberry Pi には もともと RTC が存在しないため、時刻が毎回リセットされてしまい、リブート直後の messages がデフォルトだといろいろ汚くなりがちなのと、NTP が動けない環境だと DNSSEC のバリデーションに影響が出てしまう。

[2019/04/07]
・起動時にモジュールをロードするための設定ファイル作成を追記

■今回買ってきたモジュール
・パッケージとモジュール

・モジュール拡大

・裏面のバッテリーボックス

・バッテリーの取り付け

EP-0059 Raspberry Pi RTC Module というもの。
正式には DS1307 RTC Module with BAT for Raspberry Pi SKU: EP-0059 というらしい。
GPIO のピンに刺さるコネクタがついているので便利・w・
千石電商 にて \990 で購入>w<
なお、必要なバッテリーである CR1220 も、千石電商 にて購入・w・

■認識方法
基本的には上記に記した販売元のサイトの製品紹介ページに書いてあった。
DS1307 RTC Module with BAT for Raspberry Pi SKU: EP-0059
・/boot/config.txt に追記

dtparam=i2c_arm=on
device_tree=bcm2710-rpi-3-b.dtb
dtoverlay=i2c-rtc,ds1307

その後リブートを実施し、dmesg | grep rtc 等で動作確認をして、「rtc-ds1307」の出力が確認できれば良いそうだ。

もし、CentOS7 で Kernel 4.19 以降を使っている場合、次の追加手順が必要となる。
■Kernel 4.19 以降の CentOS7 での追加手順

# vi /etc/sysconfig/modules/rtc-ds1307.modules
# chmod +x /etc/sysconfig/modules/rtc-ds1307.modules

●/etc/sysconfig/modules/rtc-ds1307.modules の中身

#!/bin/sh

if [ ! -c /dev/rtc0 ] ; then
	exec /sbin/modprobe rtc-ds1307 >/dev/null 2>&1
fi

■動作確認

# hwclock -w && date && hwclock -r
Mon Aug 27 01:32:00 JST 2018
Mon Aug 27 01:32:01 2018  -0.988717 seconds

上記のように、時刻を書き込んだ後に現在時刻と書き込んだ時刻が合っていれば問題ないはず。
なお、hwclock の呼び出し時に発生するディレイが、赤色のところ。だと思う()
念のため確認

# time hwclock -r
Mon Aug 27 01:35:37 2018  -0.887982 seconds

real    0m0.898s
user    0m0.001s
sys     0m0.024s

まあ、1秒近くかかってるし、たぶんそうだろう。

■起動時に RTC から時刻を読み込むようにする
このままでは、RTC が付いただけであり、起動時にこれは読み込まれない。
普通の IA サーバの場合、RTC を BIOS/UEFI 経由で OS に渡してくれるが、RPi にはそんな機能はない。
なので、OS 起動時に時刻を渡す必要がある。
今回は CentOS7 なので、systemd のファイルを書くことにする。
そのためには、systemd での起動順番を調べ、なるだけ早くにロードできるようにしたい。

・systemd-analyze での起動順番調査
systemd の起動順番や依存関係を調査するのに良く用いられるのが [systemd-analyze] というもの。
これを使えば、SVG 形式でプロットを作成することができる。

# systemd-analyze plot > systemd.svg

上記コマンドでの出力結果が、こんな感じ。

SVG ファイルはこちら [20180827_systemd_plot_01.svg]
これを見るに、「local-fs.target」が読まれた後に起動すれば角が立たなそうかな?

・systemd のユニットファイルを作成する
「local-fs.target」の後に起動するようにしたユニットファイルは、次の通り。

[Unit]
Description = SystemClock set from RTC.
After=local-fs.target

[Service]
ExecStart=/sbin/hwclock -s
Restart=no
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Description はユニットの説明。
After でユニットの順序を指定。今回は local-fs.target より後に起動する必要があるため、このように記述。
ExecStart には、フルパスでコマンドを書く。
Restart するわけじゃないので no と書く。
Type には oneshot と表記。今回はサービスとして起動しっぱなしにならないためである。
RemainAfterExit には yes と書く。プロセスが終了していたとしても正常とみなすためには必須。

上記内容を /etc/systemd/system/multi-user.target.wants/hwclock.service あたりに直接書き込んでしまえばよい・w・

■設定後の確認
・リブート試験

# systemctl status hwclock.service
 hwclock.service - SystemClock set from RTC.
   Loaded: loaded (/etc/systemd/system/multi-user.target.wants/hwclock.service; bad; vendor preset: disabled)
   Active: active (exited) since Mon 2018-08-27 01:57:55 JST; 1min 32s ago
  Process: 259 ExecStart=/sbin/hwclock -s (code=exited, status=0/SUCCESS)
 Main PID: 259 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/hwclock.service

Jan 01 09:00:08 RaspberryPi systemd[1]: Starting SystemClock set from RTC....
Aug 27 01:57:55 RaspberryPi systemd[1]: Started SystemClock set from RTC..

問題なく Active: active (exited) していることを確認・w・
ログ上でも、実行された後に時間が合った状態になっている。
真っ先に hwclock.service が上がったため、/var/log/messages 上でも起動開始時のログの一行目としてみることができた・w・
何より、UNIX Time 0 (UTC:1970-01-01T00:00:00 JST:1970-01-01T09:00:00) に戻っていないところがいい感じ。

Aug 27 01:57:37 RaspberryPi systemd: Stopping Session 1 of user root.
Aug 27 01:57:37 RaspberryPi systemd: Stopping Authorization Manager...
Aug 27 01:57:37 RaspberryPi systemd: Stopped target Timers.
Aug 27 01:57:37 RaspberryPi systemd: Stopping Timers.
Aug 27 01:57:37 RaspberryPi systemd: Stopping Session 2 of user admin.
Aug 27 01:57:37 RaspberryPi systemd: Stopped Dump dmesg to /var/log/dmesg.
Aug 27 01:57:37 RaspberryPi systemd: Stopping Dump dmesg to /var/log/dmesg...
Aug 27 01:57:55 RaspberryPi systemd: Started SystemClock set from RTC..
Aug 27 01:57:55 RaspberryPi systemd: Started Dump dmesg to /var/log/dmesg.

(末尾2行が、起動時のログ。)

・設定後の systemd-analyze plot 結果

SVG ファイルはこちら [20180827_systemd_plot_02.svg]
しっかり hwclock.service が rsyslog.service よりも前に読まれてるね>w<
結果、次のようにログが出力されるようになった。
– 設定前

Jan  1 09:00:39 RaspberryPi systemd: Started The Apache HTTP Server.
Aug 27 01:07:06 RaspberryPi systemd: Time has been changed
Aug 27 01:07:06 RaspberryPi ntpdate[1150]: step time server 133.243.238.243 offset 1535299584.357009 sec
Aug 27 01:07:06 RaspberryPi rsyslogd: imjournal: journal reloaded... [v8.24.0 try http://www.rsyslog.com/e/0 ]
Aug 27 01:07:06 RaspberryPi systemd: Started Set time via NTP.

– 設定後

Aug 27 01:58:24 RaspberryPi systemd: Started The Apache HTTP Server.
Aug 27 01:58:27 RaspberryPi systemd: Time has been changed
Aug 27 01:58:27 RaspberryPi ntpdate[1145]: step time server 133.243.238.164 offset 0.501060 sec
Aug 27 01:58:27 RaspberryPi systemd: Started Set time via NTP.

rsyslog が動く前に時刻同期するようになったため、systemd-journald 内で時間を補正し、rsyslog が起動したときには補正済みの時間が渡されてるようだ。

カテゴリー: めも パーマリンク

1 Response to Raspberry Pi 用の Real-Time Clock (RTC) モジュールを導入してみた@CentOS7

  1. ピンバック: Raspberry Pi で Linux Kernel 4.19.X を動かしたとき一部 HAT が動かない件について | まこぴかっと

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です