NanoPi NEOをNTPサーバにしているのだが、このシングルボードコンピューターはRTCが「なんちゃって」なので電源を切る(再起動する)と時刻情報が失われてしまう。一応システム起動時にネットワーク経由で時間合わせをするようにしているがせめて日時くらいは自分で持っててよと思う。それと、時刻のズレ方が盛大。1日で1秒2秒程度のズレならまぁかわいいものだが、NanoPi NEOでは使い方によっては酷ければ見ている内にどんどんズレてしまうほど。これは全く信用ならないのでRTCモジュールが欲しいと思ってたけど面倒と思う気持ちが勝って長らく放置してた。
例によってAliExpressで購入。2020年6月30日の購入時は商品価格が131円で送料無料だったけど、その後送料が50円前後発生している模様。なお、この製品およびリンク先がDS3231の本物チップを搭載したRTCモジュールであること、本物を販売するショップであることを保証するものではありません。
届いたRTCモジュールが上。下は大きさ比較用のmicroSDカード。基板としては小さいけどRTCモジュールとしては大きいかしら?
電池を付ける側。この面は電池ホルダーだけ。このモジュールは電池による時刻のバックアップができる(半分はそれが目的で買ってる)が、電池自体は付属していない。大きさ的には100均ショップなどでも入手できるCR2032のボタン電池が合う。
反対の面。メインのチップはDS3231SNと書かれている。これが偽チップでなければ-40℃〜85℃対応なTCXOのちょっと良いやつ。DS3231SだとTCXOだけど寒い側非対応の0℃〜70℃。誤差は0℃〜40℃で±2ppm,他±3.5ppm。
DS3231MやDS3231MZだと「DS3231はTCXOである」ことを期待して購入した筈がTCXOではなくmicroelectromechanical system(MEMS)というやつで温度は-40℃〜85℃対応だけど±5ppm (±0.432秒/日)らしいので注意。
DS3231の下の(ATMTC086) 24C32N はEEPROM。DS3231のアドレスは0x68固定とのことだがアドレスはEEPROMのアドレスは初期値が0x57で0x50から0x57の間で変更可能のよう。アドレス変更は基板上のA0,A1,A2で。
このモジュールはLIR2032という充電可能な電池を想定して作られているので充電非対応のCR2032を使うのは電池破裂等の危険があるので普通にNGというか絶対ダメ。ただし、基板上の抵抗を1つ外すことで非充電にしてCR2032ボタン電池を使うことができるようになる。画像の赤い下向け矢印のところにある抵抗で、1つ前の画像では抵抗が付いているが、この画像では既に抵抗を取り除いている。外し方としては超先細のラジオペンチなどで抵抗を挟んで砕くというのでも良いけど普通ははんだこてで温めてはんだを吸い取りながら抵抗を外すかな。今回は一応温めて丁寧に取り除いた。
このモジュールにはプルアップ抵抗が付いている。Raspberry Piではプルアップ抵抗が要らない(邪魔)ので外すらしいが、NanoPi NEOでは必要なようなのでRasbberryPi用の記事をそのまま信じてプルアップ用抵抗まで外してしまわないこと。(画像中の黄色い右向け矢印)
抵抗を取り除いたので充電非対応のCR2032を取り付けた。なお、この電池ホルダーは電池を外すのが難しいタイプなので迂闊に電池を入れてしまうと苦労することも。抵抗を外す前に電池を入れない方が良さそう。
NanoPi NEOとRTCモジュールの接続は簡単。赤丸の付いたピンとRTCモジュールの同じ名前のピンにつなぐだけ。
micro USB端子に近い側から1ピン空けてSDA, CSLと1ピン空けてGND、この3ピンの他に一番右上の外列2つのVCC 5V出力2つのどちらか空いてる方ををRTCモジュールとつなぐ。VCCとGNDは既に別なモジュール等が使っていたら別のピンでも良いけど、VCCは3.3Vはダメで5Vにつなぐ。
今回はNanoPi NEOと接続なのでRTCモジュールの32K(32768Hz出力)とSQW(1Hz出力)のピンは使わない。
今回は以前に作ったアルミケース入りNTPサーバに取り付けた。これで半分がガラ空きだったNTPサーバのケースの中がなんとか埋まった感じ。
NanoPi NEOなどH3なSoCのシングルボードコンピュータでは以下のファイルを確認。(Armbianの場合)
/boot/dtb/overlay/README.sun8i-h3-overlays
### cir Activates CIR (Infrared remote) receiver CIR pin: PL11 ### i2c0 Activates TWI/I2C bus 0 I2C0 pins (SCL, SDA): PA11, PA12 ### i2c1 Activates TWI/I2C bus 1 I2C1 pins (SCL, SDA): PA18, PA19 ### i2c2 Activates TWI/I2C bus 2 I2C2 pins (SCL, SDA): PE12, PE13 On most board this bus is wired to Camera (CSI) socket
README.sun8i-h3-overlays内でI2C0を検索して辺りを見ると i2c0 そのままの名前がある。
これを/boot/armbianEnv.txtのoverlays行に追加する。
PPS有効化のために既に書かれている内容に追記する形。(黄字部分)
overlays=uart1 pps-gpio i2c0
システムを再起動する。
$ sudo apt install i2c-tools #i2c-toolsをインストール $ sudo i2cdetect -y 0 We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
0x68(黄字部分)の方がRTCで0x57の方がこのモジュールに載っているeeprom(使わない)
$ lsmod | grep rtc
この時点ではおそらく何も出ない。
$ sudo modprobe -c | grep ds3231
alias i2c:ds3231 rtc_ds1307
alias of:N*T*Cmaxim,ds3231 rtc_ds1307
alias of:N*T*Cmaxim,ds3231C* rtc_ds1307
DS3231専用は無くてDS1307用のAliasになってるみたい。
$ sudo modprobe i2c:ds3231 $ sudo lsmod | grep rtc rtc_ds1307 28672 0
敢えてi2c:ds3231を指定したが、素直にrtc_ds1307で良いかと。
次にやりたいのはこのコマンドの送信。
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
$ sudo echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
-bash: /sys/class/i2c-adapter/i2c-0/new_device: Permission denied
怒られた。もちろん、su - や sudo -s でrootになってからなら問題ない。
$ echo ds1307 0x68 | sudo tee /sys/class/i2c-adapter/i2c-0/new_device
これなら一般ユーザーからでもいける。
$ lsmod | grep rtc
rtc_ds1307 28672 0
もういちどlsmodしたところrtc_ds1307が出現している。
$ sudo i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --0x68がUUになった。(動作中)
$ sudo hwclock -r -f /dev/rtc0 2020-07-15 14:48:15.696917+09:00 $ sudo hwclock -r -f /dev/rtc1 2020-07-15 14:48:28.614543+09:00少なくとも2秒以内に2つのRTCの時刻を連続表示したが、13秒ほどズレている。
$ ls -l /dev | grep rtc
lrwxrwxrwx 1 root root 4 Feb 14 2019 rtc -> rtc0
crw------- 1 root root 252, 0 Feb 14 2019 rtc0
crw------- 1 root root 252, 1 Jul 15 13:50 rtc1
rtc1が出来ている。これが追加したRTCモジュール。しかし、/dev/rtcは/dev/rtc0にシンボリックリンクになっているのでこれをrtc1に向かせる。
$ sudo ln -f -s /dev/rtc1 /dev/rtc
既存の/dev/rtc0に向いてるのをrtc1に強制張り替え
$ ls -l /dev | grep rtc
lrwxrwxrwx 1 root root 9 Jul 15 14:08 rtc -> /dev/rtc1
crw------- 1 root root 252, 0 Feb 14 2019 rtc0
crw------- 1 root root 252, 1 Jul 15 13:50 rtc1
/etc/rc.local (exit 0の前あたりに挿入)/usr/sbin/modprobe i2c:ds3231 echo 'ds1307 0x68' > /sys/class/i2c-adapter/i2c-0/new_device ln -f -s /dev/rtc1 /dev/rtc hwclock -f /dev/rtc1 -s
追加したRTCモジュールが使えているのは確かなようだが、「なんちゃってRTC」からの切り替えがこれでできてるのかな? なんかイマイチ確信が持てない。
あと、さきほどlsmodした結果が要らないモジュールだらけだったので対応。
$ lsmod
Module Size Used by
rtc_ds1307 28672 0
zstd 16384 4
zram 24576 2
zsmalloc 20480 1 zram
snd_soc_simple_card 20480 0
sun8i_codec_analog 24576 0
snd_soc_simple_card_utils 20480 1 snd_soc_simple_card
sun4i_i2s 24576 0
sun8i_adda_pr_regmap 16384 1 sun8i_codec_analog
sunxi_cedrus 32768 0
snd_soc_core 131072 4 sun4i_i2s,sun8i_codec_analog,snd_soc_simple_card_utils,snd_soc_simple_card
v4l2_mem2mem 20480 1 sunxi_cedrus
ac97_bus 16384 1 snd_soc_core
videobuf2_dma_contig 20480 1 sunxi_cedrus
snd_pcm_dmaengine 16384 1 snd_soc_core
videobuf2_memops 20480 1 videobuf2_dma_contig
videobuf2_v4l2 20480 2 sunxi_cedrus,v4l2_mem2mem
snd_pcm 69632 3 sun4i_i2s,snd_pcm_dmaengine,snd_soc_core
sun4i_gpadc_iio 16384 0
videobuf2_common 36864 3 sunxi_cedrus,v4l2_mem2mem,videobuf2_v4l2
industrialio 53248 1 sun4i_gpadc_iio
snd_timer 28672 1 snd_pcm
videodev 151552 4 sunxi_cedrus,videobuf2_common,v4l2_mem2mem,videobuf2_v4l2
snd 49152 3 snd_timer,snd_soc_core,snd_pcm
sun8i_thermal 16384 0
soundcore 16384 1 snd
mc 36864 5 sunxi_cedrus,videobuf2_common,videodev,v4l2_mem2mem,videobuf2_v4l2
sun4i_tcon 28672 0
sun8i_mixer 36864 0
sun8i_tcon_top 16384 1 sun4i_tcon
evdev 20480 1
pps_gpio 16384 1
uio_pdrv_genirq 16384 0
uio 16384 1 uio_pdrv_genirq
cpufreq_dt 20480 0
usb_f_acm 20480 1
u_serial 24576 3 usb_f_acm
g_serial 16384 0
libcomposite 45056 2 g_serial,usb_f_acm
ip_tables 24576 0
x_tables 24576 1 ip_tables
autofs4 36864 2
fixed 20480 2
gpio_keys 20480 0
sndとかv4l2などが目立つかな。
/etc/modprobe.d/にはblacklist-nanopineo.confがあったので今回は新しくファイルは作らずにそのファイルに追記。blacklist lima #もともと入ってた blacklist ac97_bus blacklist mc blacklist snd blacklist snd_pcm blacklist snd_pcm_dmaengine blacklist snd_soc_core blacklist snd_soc_simple_card blacklist snd_soc_simple_card_utils blacklist snd_timer blacklist sun4i_i2s blacklist sun8i_adda_pr_regmap blacklist sun8i_codec_analog blacklist sunxi_cedrus blacklist v4l2_mem2mem blacklist videobuf2_common blacklist videobuf2_v4l2 blacklist videodev
起動中のシステムから手動で外すなら modprobe -r ac97_bus など。ただし、撥ねられるかも。
再起動するとこんな感じ
$ lsmod
Module Size Used by
zstd 16384 4
zram 24576 2
zsmalloc 20480 1 zram
sun4i_gpadc_iio 16384 0
industrialio 53248 1 sun4i_gpadc_iio
sun8i_thermal 16384 0
sun4i_tcon 28672 0
sun8i_tcon_top 16384 1 sun4i_tcon
sun8i_mixer 36864 0
evdev 20480 1
pps_gpio 16384 1
uio_pdrv_genirq 16384 0
uio 16384 1 uio_pdrv_genirq
cpufreq_dt 20480 0
rtc_ds1307 28672 0
usb_f_acm 20480 1
u_serial 24576 3 usb_f_acm
g_serial 16384 0
libcomposite 45056 2 g_serial,usb_f_acm
ip_tables 24576 0
x_tables 24576 1 ip_tables
autofs4 36864 2
fixed 20480 2
gpio_keys 20480 0
うん、だいぶスッキリ。
今回はNTPサーバにRTCモジュールを付けたけど目に見えるような効果あるかしら?ntpdで統計情報を録っているので暫く動かして何か変わるか様子を見る予定。
関連記事: