前回の記事では、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を返したりしてくれればたぶん大丈夫です。
さいごに
前回の記事で行ったようにデバイスツリーに登録した方がラズパイっぽいんでしょうかね。
この辺の記事を読んで勉強すれば出来るんでしょうが、目的は達成したので今回はここまでとさせていただきます。