Raspberry Piの時計をRTCモジュールを使って電源OFF・オフラインでも狂わないようにする(RX8900編)

Pocket

前回の記事では、DS3231というMaximのi2cインターフェースを備えたリアルタイムクロックのチップを使用してRaspberry Piの時計を電源OFFでも狂わないようにしました。

今回はエプソンのRX8900というチップを使ってRaspberry PiにRTCを追加してみます。DS3231はRaspbianに最初からドライバが入っていたのですが、RX8900は入っていないので自分で用意する必要があります。

今回の記事では、検証用に購入した秋月電子さんが販売している『高精度RTC(リアルタイムクロック) RX8900 DIP化モジュール』を使用します。

はじめに

上にも書きましたが、RX8900のRTCドライバは標準で入っていないので、自分で作成する必要があります。そして、ドライバを作成するにはソースコードをコンパイルする必要があります。

今回の手順では、コンパイルするためのRaspberry Piと、実際にRTCを動作させるRaspberry Piの二つの環境が登場します。

この二つの環境では、Kernelのバージョンが一致している必要があります。普通の手順でRaspberry Piの起動ディスクを作成する場合、NOOBSを使うかイメージファイルをダウンロードして書き込むと思いますが、同一のファイルを使用していれば大丈夫です。あと、コンパイル環境と動作環境が同一でも、もちろんOKです。

なお、これより先は主に次の情報を参考にさせていただきました。
・エプソンが公開しているドライバ中のドキュメント(rx8900_k3.8-v1.0.zip内にあるRX8900_readme.pdf)
Raspberrypi3でデバイスドライバを作る
|RV-8803-C7 高精度RTCの評価ボード(バックアップ電池付き)・ラズパイなどではんだ付け無しで評価テスト |
GitHub notro/rpi-source の wiki
Raspberry Piの時計をRTCモジュールを使って電源OFF・オフラインでも狂わないようにする(2019年8月版) ←自分の記事

接続して認識するか確認

【動作環境にて実施】
i2cを有効にしていない場合はまず有効にします。方法はRaspberry PiのI2Cを使って電圧を測定する(2019年3月版)の記事をご参照ください。

有効にしたら、秋月電子さんのモジュールをRaspberry Piに接続します。私は次のようにしました。

接続したら、ターミナルで”i2cdetect -y 1″と入力します。

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: -- -- -- -- -- -- -- --  

0x32のアドレスで認識されました。大丈夫そうです。

ドライバの作成

【コンパイル環境にて実施】
まず、ドライバをコンパイルできるように設定します。

pi@raspberrypi:~ $ sudo apt-get install git bc bison flex libssl-dev
pi@raspberrypi:~ $ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update
pi@raspberrypi:~ $ rpi-source

これでドライバのコンパイルに必要なファイルがダウンロードされ、ドライバがコンパイルできる状態になります。

次にドライバのソースコードからドライバを作成します。ドライバのソースコードはエプソンのWEBサイトで公開されているので、それを使用します。
リアルタイムクロックモジュール用 Linux® Driverダウンロードページにある「使用許諾ページを経てダウンロードページへ進む」のリンクをたどればダウンロードできます。
zipファイルになっているので解凍すると、中に「rtc-rx8900.c」というファイルがあります。これがドライバのソースコードです。

pi@raspberrypi:~ $ unzip rx8900_k3.8-v1.0.zip
Archive:  rx8900_k3.8-v1.0.zip
  inflating: RX8900/GNU- General Public License_v2.pdf
   creating: RX8900/rx8900/
  inflating: RX8900/rx8900/BBB-RX8900-00A0.dtbo
  inflating: RX8900/rx8900/BBB-RX8900-00A0.dts
  inflating: RX8900/rx8900/ioctl.c
  inflating: RX8900/rx8900/rtc-rx8900.c
  inflating: RX8900/rx8900/rtctest.c
  inflating: RX8900/RX8900_readme.pdf
pi@raspberrypi:~ $ cd RX8900/rx8900/
pi@raspberrypi:~/RX8900/rx8900 $ ls -l
合計 44
-rw-r--r-- 1 pi pi  1114  1月 17  2014 BBB-RX8900-00A0.dtbo
-rw-r--r-- 1 pi pi  1246  1月 17  2014 BBB-RX8900-00A0.dts
-rw-r--r-- 1 pi pi  2472  1月 15  2014 ioctl.c
-rw-r--r-- 1 pi pi 23773  1月 23  2014 rtc-rx8900.c
-rw-r--r-- 1 pi pi  5817  5月 21  2013 rtctest.c

このソースコードをコンパイルするためにMakefileを作ります。

vi Makefile

KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build

obj-m := rtc-rx8900.o

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

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

ちなみに、上のインデントが半角スペース4つになっているかもしれませんが、TABに置き換えてください。インデントはTABじゃないとエラーになるので注意してください。

それではコンパイルします。

pi@raspberrypi:~/RX8900/rx8900 $ make
pi@raspberrypi:~/RX8900/rx8900 $ ls -l
合計 96
-rw-r--r-- 1 pi pi  1114  1月 17  2014 BBB-RX8900-00A0.dtbo
-rw-r--r-- 1 pi pi  1246  1月 17  2014 BBB-RX8900-00A0.dts
-rw-r--r-- 1 pi pi   193  8月 26 00:40 Makefile
-rw-r--r-- 1 pi pi     0  8月 26 00:40 Module.symvers
-rw-r--r-- 1 pi pi  2472  1月 15  2014 ioctl.c
-rw-r--r-- 1 pi pi    44  8月 26 00:40 modules.order
-rw-r--r-- 1 pi pi 23773  1月 23  2014 rtc-rx8900.c
-rw-r--r-- 1 pi pi 15312  8月 26 00:40 rtc-rx8900.ko
-rw-r--r-- 1 pi pi  2033  8月 26 00:40 rtc-rx8900.mod.c
-rw-r--r-- 1 pi pi  4436  8月 26 00:40 rtc-rx8900.mod.o
-rw-r--r-- 1 pi pi 12844  8月 26 00:40 rtc-rx8900.o
-rw-r--r-- 1 pi pi  5817  5月 21  2013 rtctest.c

「rtc-rx8900.ko」がドライバです。ちゃんと出来ています。このファイルを動作環境へコピーします。

ドライバの設定と動作確認

【動作環境にて実施】
「rtc-rx8900.ko」を所定のフォルダへコピーします。

pi@raspberrypi:~ $ sudo cp rtc-rx8900.ko /lib/modules/`uname -r`/
pi@raspberrypi:~ $ sudo depmod
pi@raspberrypi:~ $ sudo modprobe rtc-rx8900
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:~ $ sudo sh -c 'echo rx8900 0x32 > /sys/class/i2c-adapter/i2c-1/new_device'
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:~ $ timedatectl status
               Local time: 月 2019-08-26 00:50:11 JST
           Universal time: 日 2019-08-25 15:50:11 UTC
                 RTC time: 日 2019-08-25 15:50:12
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

i2cdetectの結果が UU になり、timedatectlもRTC timeを返してくれました。大丈夫そうです。

OSの設定

【動作環境にて実施】
ドライバが動作することが確認できました。あとは不要なパッケージを削除し、起動時にドライバが認識されるようにします。

pi@raspberrypi:~ $ sudo apt-get purge fake-hwclock
pi@raspberrypi:~ $ sudo vi /etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

echo rx8900 0x32 > /sys/class/i2c-adapter/i2c-1/new_device
/sbin/hwclock --hctosys

exit 0


echo rx8900 0x32 > /sys/class/i2c-adapter/i2c-1/new_device
/sbin/hwclock --hctosys

上記2行が追加した行です。

再起動してi2cdetectの結果が UU になったり、timedatectlがRTC timeを返したりしてくれればたぶん大丈夫です。

さいごに

前回の記事で行ったようにデバイスツリーに登録した方がラズパイっぽいんでしょうかね。
この辺の記事を読んで勉強すれば出来るんでしょうが、目的は達成したので今回はここまでとさせていただきます。

Pocket

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください