Raspberry Pi 高精度RTC(RX8900)を使用した時刻保持

Raspberry Pi

はじめに

Raspberry Piには、RTC(Real Time Clock)呼ばれるハードウェア・クロックが搭載されていないため、電源をOFFにすると時計が止まります。次に電源をONにした時は、前回電源をOFFにした時刻から時計が再開されます。インターネットに接続されている環境では、電源をONにしたときにインターネット上に存在する NTP(Network Time Protocol)サーバと呼ばれる現在時刻を配信しているサーバと時刻合わせが行われるため、時刻がずれることはありません。しかし、インターネットに接続されていない環境では、電源をONにしたときにNTPサーバと時刻同期ができないため、時刻がずれてしまいます。このため、インターネットに接続できない環境で正確な時刻を保持するには、RTC(Real Time Clock)と呼ばれるモジュールが必要になります。
RTC モジュールは、バッテリーでバックアップされており、電源をOFFにした状態でも内部で時刻を保持する機能をもっているため、NTPサーバと時刻同期ができない環境でも正確な時刻を保持できるようになります。
本文章では、EPSONの高精度RTCモジュールRX8900SAというデバイスを使用して時刻を保持する方法について記載します。

環境

  1. ボード
    Raspberry Pi 4 Model B
  2. OS
    Raspberry Pi OS (32-bit) Lite
    Minimal image based on Debian Buster
    Version: August 2020
    Release date: 2020-08-20
    Kernel version: 5.4

EPSON RX8900SAについて

RX8900SAは、 I2Cバスインターフェイスを使用したリアルタイムクロックモジュールで、温度補償発振器(DTCXO)搭載し、⾼精度かつ電源切替回路搭載したモジュールです。
以下に機能概要について記載します。

  • 32.768 kHz高精度温度補償発振器(DTCXO)を搭載
  • インターフェイス方式:I2C-Bus(Fast-Mode 400 kHz)
  • 高精度:±5.0 * 10-6 / -40℃~+85℃(月差 ± 13秒相当)
  • 電源切替機能:VDD 電圧を監視しバックアップ電源に切替
    バックアップ電源切替電圧:1.9V Min.
  • クロック出力機能
    出力周波数選択可能(32.768 kHz、1024 Hz、1 Hz)
  • ウェイクアップタイマー機能
    ソースクロック(1/60 Hz、1 Hz、64 Hz、4096 Hz)から選択して 244 μs から 2.8 ⽇までのタイマー時間が設定可能(12 bit × 1 ch)。
    タイマー完了時に /INT 端⼦から割り込み出⼒後オートリリース。
    この動作は指定された周期でオートリピートされるので、ウォッチドッグタイマーのような使い⽅も可能
  • アラーム機能
    曜~分をプログラム可能
  • インターフェイス電圧範囲:2.5 V ~ 5.5 V
  • 温度補償動作電圧範囲:2.0 V ~5.5 V
  • 計時(保持)電圧範囲:1.6 V ~5.5 V

詳細は、EPSONの製品情報サイトをご参照ください。
ここでは、以下のRX8900搭載高精度RTCモジュール基板を使用します。

RX8900SA搭載高精度RTCモジュール基板

上記の「RX8900搭載高精度RTCモジュール」をご希望の方に、説明書、モジュール基盤、ケーブル(Grove互換4ピンコネクターQI4ピン・メス)をセットで販売しています。
注)バックアップバッテリー(CR2032)は、含まれていません。
ご希望の方は、問い合わせフォームより、お気軽にご連絡ください。

Raspberry Pi OSのアップデート

はじめに、以下のコマンドを実行しRaspberry Pi OSを最新の状態にアップデートします。

pi@raspberrypi:~ $ sudo apt update
pi@raspberrypi:~ $ sudo apt upgrade
pi@raspberrypi:~ $

アップデートが終了したら、以下のコマンドを実行し、必ず再起動を行って下さい。

pi@raspberrypi:~ $ sudo reboot

アップデートを行ったときに、カーネルバージョンがアップデートされることがあります。
カーネルバージョンがアップデートされている場合に再起動を行わずカーネルヘッダーのソースコードをインストールすると、カーネルバージョンとカーネルヘッダーのバージョンが一致しなくなり、ドライバモジュールのビルドに失敗する場合があるためです。

I2Cバスインターフェイスの有効化

RX8900SAは、I2Cバスインターフェイスで接続して使用します。Raspberry Piでは、インストール後の初期状態では、I2Cバスインターフェイスが無効化されていますので、有効化する必要があります。
I2Cバスインターフェイスを有効化する方法には、「raspi-config」コマンドを使用して有効化する方法と「/boot/config.txt」を直接編集して有効化する方法があります。ここでは、「/boot/config.txt」を直接編集して有効化します。
以下のように「/boot/config.txt」ファイルを編集します。
「#dtparam=i2c_arm=on」の行のコメントアウトを削除します。

pi@raspberrypi:~ $ sudo vi /boot/config.txt
(略)
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on   <-- コメントアウトを削除する。
#dtparam=i2s=on
#dtparam=spi=on
(略)
pi@raspberrypi:~ $

「/boot/config.txt」ファイルを編集後、I2Cバスインターフェイスを有効化するため、再起動を行います。

pi@raspberrypi:~ $ sudo reboot

I2Cバスインターフェイスの有効化確認

I2Cバスインターフェイスが有効化されていることを確認します。
以下のコマンドを実行し、「spi_bcm2835」モジュールがロードされていることを確認します。

pi@raspberrypi:~ $ lsmod | grep i2c
i2c_bcm2835            16384  0
i2c_dev                20480  0
pi@raspberrypi:~ $

以下のコマンドを実行し、/dev ディレクトリにI2Cのデバイスファイル「i2c-1」が作成されていることを確認します。

pi@raspberrypi:~ $ ls -l /dev | grep i2c
crw-rw---- 1 root i2c      89,   1 Nov  3 21:28 i2c-1
pi@raspberrypi:~ $

i2c-toolsの準備

以下のコマンドを実行し、「i2c-tools」パッケージをインストールします。
「i2c-tools」パッケージには、コマンドラインからI2Cバスインターフェイスを使用して、I2Cデバイスへアクセスするための様々なコマンドが含まれています。

pi@raspberrypi:~ $ sudo apt install i2c-tools
pi@raspberrypi:~ $

RX8900SA RTCモジュールとの接続

Raspberry PiのGPIOピンとRX8900SA RTCモジュールの端子を接続します。

Raspberry Pi
GPIO ピン
RX8900SA RTC
モジュールピン
1番ピン:3V3 powerVDD ピン
3番ピン:GPIO 2 (SDA)SDA ピン
5番ピン:GPIO 3 (SCL)SCL ピン
9番ピン:GroundGND ピン
表1:Raspberry PiとRX8900SAとの接続
写真3:Raspberry PiとRX8900 RTCモジュールとの接続

接続確認

Raspberry PiとRX8900SA RTCモジュールを接続した後、以下のようにコマンドを実行します。

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- 32 -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~ $

「32」と表示されていれば、正しく接続され認識されています。
「32(0x32)」は、RX8900SA RTCモジュールに予め割り当てれているI2C デバイスのアドレスです。

RX8900ドライバモジュールの作成

RX8900 RTCモジュールを使用するためには、ドライバモジュールが必要なります。しかし、Raspberry Piのインストール後の初期状態では、RX8900 RTCモジュールのドライバモジュールがインストールされていません。このため、別途、RX8900 RTCモジュールのドライバモジュールのビルドする必要があります。

ビルド環境の準備

ドライバモジュールをビルドするために必要なパッケージをインストールします。
Raspberry Piをインストールした後の初期状態で、gccやgcc++、make等のビルドに必要なツールは既にインストールされています。しかし、ドライバモジュールをビルドするためには、現在使用しているカーネルのバージョンと同じバージョンのカーネルヘッダーのソースコードが必要になります。
以下のコマンドを実行し、現在使用しているカーネルのバージョンを確認します。

pi@raspberrypi:~ $ uname -r
5.4.72-v7l+
pi@raspberrypi:~ $

以下のようにコマンドを実行し、カーネルヘッダーのソースコードをインストールします。
(カーネルヘッダーのソースコードのインストールには、しばらく時間がかかります。)

pi@raspberrypi:~ $ sudo apt install raspberrypi-kernel-headers
pi@raspberrypi:~ $

カーネルヘッダーのソースコードは、「/usr/src/linux-headers-<カーネルのバージョン>」にインストールされます。(例えば、カーネルのバージョンが「5.4.72-v7l+」の場合は、「/usr/src/linux-headers-5.4.72-v7l+」にインストールされます。)

pi@raspberrypi:~ $ ls -l /usr/src
total 12
drwxr-xr-x 23 root root 4096 Nov  3 13:52 linux-headers-5.4.72+
drwxr-xr-x 23 root root 4096 Nov  3 13:52 linux-headers-5.4.72-v7+
drwxr-xr-x 23 root root 4096 Nov  3 13:53 linux-headers-5.4.72-v7l+
pi@raspberrypi:~ $

以下のように、カーネルヘッダーのソースコードをインストールすると「/lib/modules/<カーネルバージョン>/build」ディレクトリが作成されます。このディレクトリは、「/usr/src/linux-headers-<カーネルのバージョン>」へのシンボリックリンク」になっています。
(※カーネルヘッダーのソースコードのインストール前は、「/lib/modules/linux-headers-<カーネルバージョン>/build」ディレクトリは存在しません。)

pi@raspberrypi:~ $ ls -l /lib/modules/
total 16
drwxr-xr-x 3 root root 4096 Nov  3 13:54 5.4.72+
drwxr-xr-x 3 root root 4096 Nov  3 13:54 5.4.72-v7+
drwxr-xr-x 3 root root 4096 Nov  4 20:32 5.4.72-v7l+
drwxr-xr-x 3 root root 4096 Nov  3 13:24 5.4.72-v8+
pi@raspberrypi:~ $ ls -l /lib/modules/5.4.72-v7l+
total 2304
lrwxrwxrwx  1 root root     34 Oct 22 23:32 build -> /usr/src/linux-headers-5.4.72-v7l+
drwxr-xr-x 11 root root   4096 Nov  3 13:24 kernel
-rw-r--r--  1 root root 563100 Nov  4 20:32 modules.alias
-rw-r--r--  1 root root 584996 Nov  4 20:32 modules.alias.bin
-rw-r--r--  1 root root  12922 Oct 22 23:25 modules.builtin
-rw-r--r--  1 root root  26231 Oct 22 23:25 modules.builtin.alias.bin
-rw-r--r--  1 root root  14310 Nov  4 20:32 modules.builtin.bin
-rw-r--r--  1 root root  60072 Oct 22 23:25 modules.builtin.modinfo
-rw-r--r--  1 root root 188471 Nov  4 20:32 modules.dep
-rw-r--r--  1 root root 261631 Nov  4 20:32 modules.dep.bin
-rw-r--r--  1 root root    324 Nov  4 20:32 modules.devname
-rw-r--r--  1 root root  63246 Oct 22 23:25 modules.order
-rw-r--r--  1 root root    355 Nov  4 20:32 modules.softdep
-rw-r--r--  1 root root 239599 Nov  4 20:32 modules.symbols
-rw-r--r--  1 root root 294603 Nov  4 20:32 modules.symbols.bin
pi@raspberrypi:~ $

ドライバモジュールの取得

次に、ドライバモジュールのソースコードを取得します。
EPSONのリアルタイムクロックモジュール用 Linux Driver ダウンロードページで、RX8900ドライバモジュール(rx8900_k3.8-v1.0.zip、2014/2/27)をダウンロードすることができますが、このドライバは古くビルドできませんでした。このため、RX8900と互換性のあるrv8803のドライバモジュールを使用します。
以下のコマンドを実行し、rv8803のドライバモジュールのソースコードをダウンロードします。
ここでは、「~/rv8803」ディレクトリにダウンロードします。このディレクトリをドライバモジュールをビルドする際の作業用ディレクトリとして使用します。

pi@raspberrypi:~ $ mkdir rv8803
pi@raspberrypi:~ $ cd rv8803/
pi@raspberrypi:~/rv8803 $ wget https://github.com/raspberrypi/linux/raw/rpi-5.4.y/drivers/rtc/rtc-rv8803.c
--2020-11-04 20:19:49--  https://github.com/raspberrypi/linux/raw/rpi-5.4.y/drivers/rtc/rtc-rv8803.c
Resolving github.com (github.com)... 52.69.186.44
Connecting to github.com (github.com)|52.69.186.44|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.4.y/drivers/rtc/rtc-rv8803.c [following]
--2020-11-04 20:19:50--  https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.4.y/drivers/rtc/rtc-rv8803.c
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.8.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.8.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15462 (15K) [text/plain]
Saving to: ‘rtc-rv8803.c’

rtc-rv8803.c                 100%[==============================================>]  15.10K  --.-KB/s    in 0.07s

2020-11-04 20:19:51 (221 KB/s) - ‘rtc-rv8803.c’ saved [15462/15462]

pi@raspberrypi:~/rv8803 $ ls -l
total 16
-rw-r--r-- 1 pi pi 15462 Nov  4 20:19 rtc-rv8803.c
pi@raspberrypi:~/rv8803 $

ドライバモジュールのビルド

ダウンロードしたrv8803ドライバモジュールのソースコードをビルドするため、以下のようにMakeFileを作成します。

pi@raspberrypi:~/rv8803 $ vi MakeFile
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build

obj-m := rtc-rv8803.o

all:
        $(MAKE) -C $(KERNEL_HEADERS) M=$(shell pwd) modules

clean:
        $(MAKE) -C $(KERNEL_HEADERS) M=$(shell pwd) clean

pi@raspberrypi:~/rv8803 $

※上記のソースコードのインデントは、TABに置き換えてください。MakeFile のインデントは、TABでなければエラーになりますので注意してください。
以下のコマンドを実行し、ドライバモジュールのソースコードをビルドします。

pi@raspberrypi:~/rv8803 $ make
make -C /lib/modules/5.4.72-v7l+/build M=/home/pi/rv8803 modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.72-v7l+'
  CC [M]  /home/pi/rv8803/rtc-rv8803.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/pi/rv8803/rtc-rv8803.mod.o
  LD [M]  /home/pi/rv8803/rtc-rv8803.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.72-v7l+'
pi@raspberrypi:~/rv8803 $

ビルドが正常に終了すると、以下のように「rtc-rv8803.ko」というファイルが作成されます。このファイルがドライバモジュールです。

pi@raspberrypi:~/rv8803 $ ls -l
total 68
-rw-r--r-- 1 pi pi   194 Nov  4 20:23 Makefile
-rw-r--r-- 1 pi pi    30 Nov  4 20:24 modules.order
-rw-r--r-- 1 pi pi     0 Nov  4 20:24 Module.symvers
-rw-r--r-- 1 pi pi 15462 Nov  4 20:19 rtc-rv8803.c
-rw-r--r-- 1 pi pi 14892 Nov  4 20:24 rtc-rv8803.ko    <-- ドライバモジュール
-rw-r--r-- 1 pi pi    30 Nov  4 20:24 rtc-rv8803.mod
-rw-r--r-- 1 pi pi  2065 Nov  4 20:24 rtc-rv8803.mod.c
-rw-r--r-- 1 pi pi  4608 Nov  4 20:24 rtc-rv8803.mod.o
-rw-r--r-- 1 pi pi 11764 Nov  4 20:24 rtc-rv8803.o
pi@raspberrypi:~/rv8803 $

ドライバモジュールの登録

以下のコマンドを実行し、作成された「rtc-rv8803.ko」ドライバモジュールを「/lib/modules/<カーネルバージョン>/」ディレクトリにコピーします。
コピー先のディレクトリは、使用しているカーネルのバージョンによってことなりますので、注意してください。

pi@raspberrypi:~/rv8803 $ sudo cp rtc-rv8803.ko /lib/modules/5.4.72-v7l+/
pi@raspberrypi:~/rv8803 $

以下のコマンドを実行し、カーネルモジュールの依存関係リスト(/lib/modules/<カーネルバージョン>/modules.dep)を更新し、作成した「rtc-rv8803.ko」ドライバモジュールを「modprobe」コマンドでロードできるようにします。

pi@raspberrypi:~/rv8803 $ cd /lib/modules/5.4.72-v7l+/
pi@raspberrypi:/lib/modules/5.4.72-v7l+ $ sudo depmod
pi@raspberrypi:/lib/modules/5.4.72-v7l+ $

「modules.dep」ファイルに「rtc-rv8803.ko」が登録されていることを確認します。

pi@raspberrypi:/lib/modules/5.4.72-v7l+ $ cat modules.dep | grep rv8803
rtc-rv8803.ko:
pi@raspberrypi:/lib/modules/5.4.72-v7l+ $

RX8900 RTCモジュールの動作確認

「modules.dep」に「rtc-rv8803.ko」ドライバモジュール が登録されると、「modprobe」コマンドを使用してドライバモジュールをロードできるようになります。
以下のコマンドを実行し、ドライバモジュールをロードします。

pi@raspberrypi:~ $ sudo modprobe rtc-rv8803
pi@raspberrypi:~ $

以下のコマンドを実行し、rv8803ドライバモジュールをRX8900 RTCモジュールのドライバとして登録します。rv8803ドライバモジュールは、rv8803またはrx8900というIDで利用できます。

pi@raspberrypi:~ $ sudo sh -c 'echo rx8900 0x32 > /sys/class/i2c-adapter/i2c-1/new_device'
pi@raspberrypi:~ $
または
pi@raspberrypi:~ $ sudo sh -c 'echo rv8803 0x32 > /sys/class/i2c-adapter/i2c-1/new_device'
pi@raspberrypi:~ $

以下のコマンドを実行し、I2Cバスインターフェイスに接続されたRX8900 RTCモジュールにドライバが適用され、「UU」と表示されていることを確認します。
(※「UU」は、ドライバモジュールが適用されていることを示しています。)

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~ $

OSのシステム時刻を合わせた後、以下のコマンドを実行し、OSのシステム時刻をRX8900 RTCモジュールに設定します。

pi@raspberrypi:~ $ sudo hwclock -w
pi@raspberrypi:~ $

以下のコマンドを実行し、OSのシステム時刻とRX8900 RTCモジュールの時刻が合っていることを確認します。

pi@raspberrypi:~ $ timedatectl status
               Local time: Wed 2020-11-04 20:49:16 JST   <--- OSのシステム時刻
           Universal time: Wed 2020-11-04 11:49:16 UTC   <--- OSのシステム時刻
                 RTC time: Wed 2020-11-04 11:49:16       <--- RX8900 RTC モジュールの時刻
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
pi@raspberrypi:~ $

以上です。

タイトルとURLをコピーしました