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

Raspberry Pi

はじめに

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

環境

  1. ボード
    Raspberry Pi 4 Model B
  2. OS
    Raspberry Pi OS with desktop and recommended software
    Release date: May 7th 2021
    Kernel version: 5.10

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)は、含まれていません。)
ご希望の方は、問い合わせフォームより、お気軽にご連絡ください。
メルカリでも販売しています。(※「rtc rx8900」で検索してください。)

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 Aug 31 22:14 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.10.52-v7+
pi@raspberrypi:~ $

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

pi@raspberrypi:~ $ sudo apt install raspberrypi-kernel-headers
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  raspberrypi-kernel-headers
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 26.3 MB of archives.
After this operation, 171 MB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian buster/main armhf raspberrypi-kernel-headers armhf 1.20210805-1 [26.3 MB]
Fetched 7,039 kB in 3s (2,359 kB/s)
Selecting previously unselected package raspberrypi-kernel-headers.
(Reading database ... 165849 files and directories currently installed.)
Preparing to unpack .../raspberrypi-kernel-headers_1.20210805-1_armhf.deb ...
Unpacking raspberrypi-kernel-headers (1.20210805-1) ...
Setting up raspberrypi-kernel-headers (1.20210805-1) ...
pi@raspberrypi:~ $

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

pi@raspberrypi:~ $ ls -l /usr/src
total 12
drwxr-xr-x 23 root root 4096 Aug 31 22:00 linux-headers-5.10.52+
drwxr-xr-x 23 root root 4096 Aug 31 22:00 linux-headers-5.10.52-v7+
drwxr-xr-x 23 root root 4096 Aug 31 22:01 linux-headers-5.10.52-v7l+
pi@raspberrypi:~ $

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

【カーネルヘッダーのインストール後】
pi@raspberrypi:~ $ ls -l /lib/modules/
total 16
drwxr-xr-x 3 root root 4096 Aug 31 22:01 5.10.52+
drwxr-xr-x 3 root root 4096 Aug 31 22:07 5.10.52-v7+
drwxr-xr-x 3 root root 4096 Aug 31 22:01 5.10.52-v7l+
drwxr-xr-x 3 root root 4096 Aug 15 22:00 5.10.52-v8+
pi@raspberrypi:~ $

pi@raspberrypi:~ $ ls -l /lib/modules/5.10.52-v7+
total 2368
lrwxrwxrwx  1 root root     34 Aug  5 21:16 build -> /usr/src/linux-headers-5.10.52-v7+ <== (※)
drwxr-xr-x 11 root root   4096 Aug 15 21:59 kernel
-rw-r--r--  1 root root 565939 Aug 31 22:07 modules.alias
-rw-r--r--  1 root root 594447 Aug 31 22:07 modules.alias.bin
-rw-r--r--  1 root root  13495 Jul 28 07:15 modules.builtin
-rw-r--r--  1 root root  24845 Jul 28 07:15 modules.builtin.alias.bin
-rw-r--r--  1 root root  14603 Aug 31 22:07 modules.builtin.bin
-rw-r--r--  1 root root  75196 Jul 28 07:15 modules.builtin.modinfo
-rw-r--r--  1 root root 195459 Aug 31 22:07 modules.dep
-rw-r--r--  1 root root 270093 Aug 31 22:07 modules.dep.bin
-rw-r--r--  1 root root    324 Aug 31 22:07 modules.devname
-rw-r--r--  1 root root  64696 Jul 28 07:15 modules.order
-rw-r--r--  1 root root    380 Aug 31 22:07 modules.softdep
-rw-r--r--  1 root root 249450 Aug 31 22:07 modules.symbols
-rw-r--r--  1 root root 304103 Aug 31 22:07 modules.symbols.bin
pi@raspberrypi:~ $

※カーネルヘッダーをインストールするとシンボリックリンク「build」が作成される。

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

次に、ドライバモジュールのソースコードを取得します。
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.10.y/drivers/rtc/rtc-rv8803.c

--2021-08-31 22:55:54--  https://github.com/raspberrypi/linux/raw/rpi-5.10.y/drivers/rtc/rtc-rv8803.c
Resolving github.com (github.com)... 13.114.40.48
Connecting to github.com (github.com)|13.114.40.48|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.10.y/drivers/rtc/rtc-rv8803.c [following]
--2021-08-31 22:55:55--  https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.10.y/drivers/rtc/rtc-rv8803.c
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.108.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15329 (15K) [text/plain]
Saving to: ‘rtc-rv8803.c’

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

2021-08-31 22:55:55 (3.48 MB/s) - ‘rtc-rv8803.c’ saved [15329/15329]

pi@raspberrypi:~/rv8803 $
pi@raspberrypi:~/rv8803 $ ls -l
total 20
-rw-r--r-- 1 pi pi 15329 Aug 31 22:55 rtc-rv8803.c
pi@raspberrypi:~/rv8803 $

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

ダウンロードしたrv8803ドライバモジュールのソースコードをビルドするため、以下のようにMakefileを作成します。
(※ファイル名は、必ず「Makefile」というファイル名にする必要があります。)

pi@raspberrypi:~/rv8803 $ vi Makefile

【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 $

※上記のソースコードの$(MAKE)~の前のインデントは、TABに置き換えてください。Makefileのインデントは、TABでなければエラーになりますので注意してください。
上手くいかない場合は以下のリンクをクリックし、Makefileをダウンロードしてご使用ください。
Makefileのダウンロード

以下のコマンドを実行し、ドライバモジュールのソースコードをビルドします。

pi@raspberrypi:~/rv8803 $ make
make -C /lib/modules/5.10.52-v7+/build M=/home/pi/rv8803 modules
make[1]: Entering directory '/usr/src/linux-headers-5.10.52-v7+'
  CC [M]  /home/pi/rv8803/rtc-rv8803.o
  MODPOST /home/pi/rv8803/Module.symvers
  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.10.52-v7+'
pi@raspberrypi:~/rv8803 $

ビルドが正常に終了すると、以下のように「rtc-rv8803.ko」というファイルが作成されます。このファイルがドライバモジュールです。
ドライバモジュールのビルドが上手くいかない場合は、以下のリンクからドライバモジュールをダウンロードしてご使用ください。(カーネルバージョン:5.10.52-v7+版)
「rtc-rv8803.ko」ドライバモジュールのダウンロード

pi@raspberrypi:~/rv8803 $ ls -l
total 68
-rw-r--r-- 1 pi pi   194 Aug 31 22:51 Makefile
-rw-r--r-- 1 pi pi    30 Aug 31 22:57 modules.order
-rw-r--r-- 1 pi pi     0 Aug 31 22:57 Module.symvers
-rw-r--r-- 1 pi pi 15329 Aug 31 22:55 rtc-rv8803.c
-rw-r--r-- 1 pi pi 14720 Aug 31 22:57 rtc-rv8803.ko <== ドライバモジュール
-rw-r--r-- 1 pi pi    30 Aug 31 22:57 rtc-rv8803.mod
-rw-r--r-- 1 pi pi  2089 Aug 31 22:57 rtc-rv8803.mod.c
-rw-r--r-- 1 pi pi  4624 Aug 31 22:57 rtc-rv8803.mod.o
-rw-r--r-- 1 pi pi 11568 Aug 31 22:57 rtc-rv8803.o
pi@raspberrypi:~/rv8803 $

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

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

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

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

pi@raspberrypi:~/rv8803 $ cd /lib/modules/5.10.52-v7+/
pi@raspberrypi:/lib/modules/5.10.52-v7+ $ sudo depmod
pi@raspberrypi:/lib/modules/5.10.52-v7+ $

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

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

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: Tue 2021-08-31 23:14:11 JST <--- OSのシステム時刻
           Universal time: Tue 2021-08-31 14:14:11 UTC <--- OSのシステム時刻
                 RTC time: Tue 2021-08-31 14:14:11 <--- RX8900 RTC モジュールの時刻
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
pi@raspberrypi:~ $

以上です。

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