はじめに
Raspberry Pi OS (Trixie)におけるリアルタイムクロックの設定方法について調べています.だいぶ以前(Jessieとか?)の時代にリアルタイムクロックを設定し,Raspberry Piで動作しているのを確認したのですが,Trixieになってからは全くここら辺について触っていませんでした.世の中にある情報で特に日本語で書かれた記事の多くはだいぶ古いものが多く,致命的なのはhwclockコマンドがTrixieには無いため,どのように設定すればよいのかわからず困っていました.まだ試行錯誤中なのでここに書いたことが全部無駄のない処理かは分かりません.ひとまず行ったことを書き残しておきます.
環境
- OS: Raspberry Pi OS Trixie
- RTC: ds1307
なお,ハードウェアはおそらく過去のものがそのまま使えそうでした.
最終的に行ったこと
- I2Cの有効化
- ds1307のモジュールを読み込む
- 自動的にRTCを読み込むこと
1についてはいろいろなところで書かれているので説明を省略します.例えばこちらをご覧ください.
2についてはds1307のモジュールを読み揉むため,modprobeを自動的に行うようにすればよいです.そのためには,/etc/modules-load.d/modules.confファイルに次の1行を追加します.
rtc-ds1307
3については,RTCをOS起動時に読み込むような設定を行います.ここではスクリプトを用意し,それをsystemdで実行するという方法で行います.まず/usr/sibnにset-rtc.shを作成しました.
#! /bin/sh # RTCデバイスがraspbianの管理下にあるかチェック # (強引ですがgrepを使って、該当アドレス68番があるか確認) /usr/sbin/i2cdetect -y 1 | grep "68" > /dev/null if [ $? = 0 ]; then #未登録なら登録する echo ds1307 0x68 > /sys/class/i2c-dev/i2c-1/device/new_device fi
その後,set-rtc.shに実行権限を以下のようにして付けました.
$ sudo chmod 700 /usr/sbin/set-rtc.sh
次に/etc/systemd/systemへsetRTC.serviceを作成しました.下がsetRTC.serviceです.
[Unit]
Description=Enable RTC
After=network.target local-fs.target
ConditionPathExists=/usr/sbin
[Service]
ExecStart=/usr/sbin/set-rtc.sh
Restart=no
KillMode=mixed
Type=oneshot
User=root
Group=root
[Install]
WantedBy=multi-user.target
最後にサービスの有効化と実行を行います.
$ sudo systemctl enable setRTC $ sudo systemctl start setRTC
以下のことは,上記の試行錯誤するうえで行ったことです.読み飛ばしでも大丈夫です.
行ったこと
- I2Cの有効化
- ds1307のモジュールをデバイスとして登録
1についてはいろいろなところで書かれているので説明を省略します.
2についてはまだよくわかっていないところですが,
$ sudo su -
# modprobe rtc-ds1307
# echo ds1307 0x68 > /sys/class/i2c-dev/i2c-1/device/new_device
とすると,RTCとして登録されそうです.
で,このあとhwclockでRTCを制御するという設定をするはずなのですが,少なくともデフォルトではhwclockがありません.代わりに何かが動いているようですが,よくわかりませんでした.とりあえず,上記の設定を行ったのち,sudo timedatectlとすると,以下のような反応になります.
Local time: Sun 2025-11-23 10:08:40 JST
Universal time: Sun 2025-11-23 01:08:40 UTC
RTC time: Sun 2025-11-23 01:08:32
Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
3行目のRTC timeについて,設定を行わないときにはn/aとなっていたことから,おそらくこの設定でRTCが動作していると思われます.試しにネットワークから未接続にして上記の設定をした結果,時間が正しく設定されるか確認してみます.このためにまずはネットワークを未接続にしたうえでシャットダウンし,5分ほど放置してから再び電源を入れます.ネットワークに接続されてもいませんし,まだRTCの設定もしていないつもりなので,5分くらい時計が遅れることを期待しています.
結果としては,まず電源を入れたのち,dateコマンドでRaspberry Piの時間を確認すると,案の定,時間が遅れていました.その後,timedatectlコマンドを実行したら,RTC timeはn/aとなっていました.その後,modprobeとechoの2行をコマンドを実行したのち,timedatectlを実行するとRTCに記憶された時刻がLocal timeやUniversal timeにも反映されました.最後にdateコマンドで時刻を確認するとRTCの時刻が表示されたことを確認できました.
ちなみにRTCに正しい時刻を設定する手続きは特に行っていませんでしたが,おそらくネットワークが接続された時,NTPから正しい時刻を取得し,ハードウェアクロックとRTCへその時刻を設定するところまで自動で行ってくれたものと思われます.
ということで,あとはOS起動時にmodprobeとechoの2行を行えるようにすればよさそうです.まずはmodprobeです./etc/modules-load.d/modules.confファイルに次の1行を追加します.
rtc-ds1307
このあとリブートし,lsmodでrtc-ds1307が起動していることを確認しました.続いてechoの実行です.ここではスクリプトを用意し,それをsystemdで実行するという方法で行います.まず/usr/sibnにset-rtc.shを作成しました.
#! /bin/sh
# RTCデバイスがraspbianの管理下にあるかチェック
# (強引ですがgrepを使って、該当アドレス68番があるか確認)
/usr/sbin/i2cdetect -y 1 | grep "68" > /dev/null
if [ $? = 0 ]; then
#未登録なら登録する
echo ds1307 0x68 > /sys/class/i2c-dev/i2c-1/device/new_device
fi
その後,chmod 700 /usr/sbin/set-rtc.shを行い,実行権限を付与しました.
次に/etc/systemd/systemへsetRTC.serviceを作成しました.下がsetRTC.serviceです.
[Unit]
Description=Enable RTC
After=network.target local-fs.target
ConditionPathExists=/usr/sbin
[Service]
ExecStart=/usr/sbin/set-rtc.sh
Restart=no
KillMode=mixed
Type=oneshot
User=root
Group=root
[Install]
WantedBy=multi-user.target
最後にサービスの有効化と実行を行います.
$ sudo systemctl enable setRTC
$ sudo systemctl start setRTC
これで再起動したらRTCが動いているはずです.仮にネットワークがつながらなくてもRTCに以前設定された正しい時刻がシステムクロックとして使われるようになります.
