Armadilloフォーラム

補正前の時刻について

nagashima

2018年8月2日 15時20分

長島と申します。お世話になります。

Armadillo-440にて、最初に起動したときの時刻を確認すると

# date
Sat Mar 24 11:54:43 JST 2018

と 2018/3/24 の時刻が表示されるのですが、こちらは何かの値なのでしょうか?

運用上はNTP&RTC時刻補正するので問題ないのですが、
1900/1/1 とか区切りのいい時刻でないのが気になりました。
ご存じの方いらっしゃいましたらご教示ください。

コメント

中村です。

> Armadillo-440にて、最初に起動したときの時刻を確認すると
>
> # date
> Sat Mar 24 11:54:43 JST 2018
>
> と 2018/3/24 の時刻が表示されるのですが、こちらは何かの値なのでしょうか?

自分が過去に作ったシステムで、起動時に時計の年が201x年以上に
なっていればRTCがバックアップされていて時計は合っているもの、
(201xは、2017年だったり2018年だったり、いろいろですが...)
というような処理をしているところがあり、
もしこういうケースがあるとすると、
その判断じゃダメということになってしまいます。

なので、この件、ちょっと気になりました。

> 1900/1/1 とか区切りのいい時刻でないのが気になりました。

400シリーズのRTCはS35390AというICを使っています。
S35390Aは年の部分は西暦の下2桁だけを管理して、
データシートによると2099年まで対応となっていますので、
リセット時(バッテリバックアップされていないとき)は2000年になります。

カーネル2.6.26の場合ですが、バッテリバックアップされていないときは、
ブートメッセージに
rtc-s35390a 2-0030: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
という表示があります。

このときに起動直後にdateを実行すると、
[root@armadillo420-0 (ttymxc1) ~]# date
Sat Jan 1 09:00:39 JST 2000
のようになります。

> ご存じの方いらっしゃいましたらご教示ください。

カーネルとユーザランドのバージョンなど、
教えていただけますか?

> # date
> Sat Mar 24 11:54:43 JST 2018

実行タイミングによって多少の違いはあるでしょうが、
2018/3/24 11:54くらいで、いつも同じなのでしょうか?

--
なかむら

中村様

長島です。お世話になっております。

> カーネルとユーザランドのバージョンなど、教えていただけますか?

基本的な情報を記載せず、失礼いたしました。

 開発環境:ATDE5
 カーネル:linux-3.14-at10
 ユーザランド:atmark-dist-20171227 のカスタマイズ
 RTCチップ:RX-8564
  ・Armadilloに接続した独自基板上(i2c-2)
  ・デバイスドライバは互換の pcf-8563 のものを使用
 
起動時に
 1. OS起動時にRTCの時刻をシステムクロックに反映
 2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
 3. システムクロックの時刻でRTCの時刻を補正
といった処理を行っており、/var/log/message は以下のようになっています。
--------
Mar 24 02:43:17 (none) syslog.info syslogd started: BusyBox v1.20.2
Mar 24 02:43:17 (none) user.notice kernel: klogd started: BusyBox v1.20.2 (2018-03-24 11:30:42 JST)
:
Mar 24 02:43:23 (none) user.info kernel: rtc-pcf8563 2-0051: chip found, driver version 0.4.3
Mar 24 02:43:23 (none) user.info kernel: rtc-pcf8563 2-0051: rtc core: registered rtc-pcf8563 as rtc0
Mar 24 02:43:23 (none) user.info kernel: i2c i2c-2: new_device: Instantiated device pcf8563 at 0x51
:
Aug 2 10:56:44 (none) user.info kernel: i2c i2c-2: delete_device: Deleting device pcf8563 at 0x51
Aug 2 10:56:45 (none) user.info kernel: rtc-pcf8563 2-0051: chip found, driver version 0.4.3
Aug 2 10:56:45 (none) user.info kernel: rtc-pcf8563 2-0051: rtc core: registered rtc-pcf8563 as rtc0
Aug 2 10:56:45 (none) user.info kernel: i2c i2c-2: new_device: Instantiated device pcf8563 at 0x51
--------

> 実行タイミングによって多少の違いはあるでしょうが、
> 2018/3/24 11:54くらいで、いつも同じなのでしょうか?

このカーネルとユーザランドだと、Armadillo単体(RTC未接続)でも、RTC接続状態でも
2018/3/24 xx:xx になります。

以上、よろしくお願いいたします。

中村です。

長島さん、追加情報、ありがとうございます。

先ほどの私が書いた内容の一部を訂正します。
(それほど重要なことではないですが)

>> 400シリーズのRTCはS35390AというICを使っています。

Armadill-460以外の400シリーズはRTCが搭載されていませんので、
アットマークテクノ社製のRTCオプションモジュール、
WLAN オプションモジュール、LCD 拡張ボードなどを
接続した場合でした。

自分で作ったA-410用のボードもこれらに合わせてS35390Aを
搭載したため、私の手元に何台かある400シリーズは全部
S35390Aなので、うっかり「400シリーズのRTCは...」と
書いてしまっていました。すみません。

> このカーネルとユーザランドだと、Armadillo単体(RTC未接続)でも、RTC接続状態でも
> 2018/3/24 xx:xx になります。

独自のRTCをお使いとのことですが、
RTC未接続でも同じ状況になるのであれば、
私の方でも試せそうです。
少し調べてみます。

--
なかむら

中村です。

> 私の方でも試せそうです。
> 少し調べてみます。

途中経過です。

3.14を書き込んだA-4x0がなかったので、
フラッシュ書き換えで時間がかかってしまいましたが、
(書き換え作業に時間がかかったというより、
書き換えてもいいA-4x0を探すのに時間が・・・)
最新の公式イメージを使って再現できました。

カーネル
linux-a400-2.06.bin.gz(3.14.36-at11)
ユーザランド
romfs-a440-2.04.img.gz(atmark-dist-20180330)
ハードウェア
Armadillo-410液晶付き開発セット
です。

液晶の接続を外してRTC非接続にした場合と、
液晶をつないでRTCありの場合のどちらでも、
長嶋さんと同じようになりました。

RTCなしのとき:
ブートメッセージ
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)

[root@armadillo440-0 (ttymxc1) ~]# date
Sat Mar 31 01:32:09 JST 2018

[root@armadillo440-0 (ttymxc1) ~]# hwclock --show
hwclock: KDGHWCLK ioctl failed, errno=25: Inappropriate ioctl for device.
Cannot access the Hardware Clock via any known method.
Use the --debug option to see the details of our search for an access method.

RTCありのとき:
ブートメッセージ
rtc-s35390a 2-0030: setting system clock to 2000-01-01 00:00:00 UTC (946684800)

[root@armadillo440-0 (ttymxc1) ~]# date
Sat Mar 31 01:34:27 JST 2018

[root@armadillo440-0 (ttymxc1) ~]# hwclock --show
Sat Jan 1 00:04:47 2000 -0.796056 seconds

uname をしてみると・・・
[root@armadillo440-0 (ttymxc1) ~]# uname -a
Linux armadillo440-0 3.14.36-at11 #1 PREEMPT Sat Mar 31 01:52:53 JST 2018 armv5tejl GNU/Linux

私の場合は2018/3/31 01:xx になりましたが、
もしかしたら、ビルド日時に関係しているのではないでしょうか?

RTC接続状態でdateコマンドで現在時刻を設定して、
hwclockでRTCに保存して、リセットボタンで再起動すると、
再起動後は現在時刻になりました。

[root@armadillo440-0 (ttymxc1) ~]# date
Sat Mar 31 01:30:55 JST 2018

[root@armadillo440-0 (ttymxc1) ~]# date 080301432018
Fri Aug 3 01:43:00 JST 2018

[root@armadillo440-0 (ttymxc1) ~]# hwclock --systohc --utc

[root@armadillo440-0 (ttymxc1) ~]# hwclock --show
Fri Aug 3 01:43:13 2018 -0.722914 seconds

リセットボタンで再起動

ブートメッセージ
rtc-s35390a 2-0030: setting system clock to 2018-08-02 16:45:50 UTC (1533228350)

[root@armadillo440-0 (ttymxc1) ~]# date
Fri Aug 3 01:46:38 JST 2018

今までは3.14使う案件がなかったのでよかったですが、
3.14を使うと、2本前の投稿で書いた、
>> 自分が過去に作ったシステムで、起動時に時計の年が201x年以上に
>> なっていればRTCがバックアップされていて時計は合っているもの、
>> (201xは、2017年だったり2018年だったり、いろいろですが...)
>> というような処理をしているところがあり、
>> もしこういうケースがあるとすると、
>> その判断じゃダメということになってしまいます。

この方法だと、RTCがバックアップされているかどうか、
判断できないですね。

もう少し調べてみます。

--
なかむら

中村です。

途中経過、その2、です。

> uname をしてみると・・・
> [root@armadillo440-0 (ttymxc1) ~]# uname -a
> Linux armadillo440-0 3.14.36-at11 #1 PREEMPT Sat Mar 31 01:52:53 JST 2018 armv5tejl GNU/Linux
>
> 私の場合は2018/3/31 01:xx になりましたが、
> もしかしたら、ビルド日時に関係しているのではないでしょうか?

これを確かめるために、ソースからデフォルトでビルドして、
カーネルとユーザランドを入れ替えてみました。
カーネルだけを入れ替えたときには、2018/3/31 01:xx で変わらず。

ユーザランドを入れ替えたところ、
[root@armadillo440-0 (ttymxc1) ~]# date
Fri Aug 3 02:36:17 JST 2018
になりました。

ユーザランドのビルド完了時刻は、
-rw-r--r-- 1 atmark atmark 15242898 8月 3 02:44 romfs.img.gz

いつ、誰が、どういう条件のときに、どこの時刻を拾ってきているのか?
探すのに時間がかかりそうです。

どなたか、ご存じないでしょうか?

--
なかむら

中村です。

見つけました。

atmark-dist-xxxx/user/flatfsd/flatfsd-3.0.2/flatfsd.c

static int read_config_from_flash(void)
{
#ifdef HAS_RTC
        time_t bst = BUILD_START_UNIX;
 
        if (time(NULL) < bst) {
                stime(&bst);
        }
#endif
        ...
}

/etc/init.d/flatfsdスクリプトの次の部分から呼ばれます。

    echo -n "Loading /etc/config: "
    flatfsd -r > /dev/null 2>&1
    check_status

--
なかむら

中村様

長島です。お世話になっております。

> もしかしたら、ビルド日時に関係しているのではないでしょうか?

2018/3/24 以降もビルドしているのですが、ATDE5 の環境を調べてみたところ、

# ls -l /home/atmark/linux-3.14-at10
:
drwxr-xr-x 3 atmark atmark 4096 3月 24 11:22 block
drwxr-xr-x 4 atmark atmark 4096 3月 24 11:22 crypto
drwxr-xr-x 115 atmark atmark 4096 4月 15 17:30 drivers
drwxr-xr-x 37 atmark atmark 4096 3月 24 11:22 firmware
drwxr-xr-x 74 atmark atmark 12288 3月 24 11:22 fs
drwxr-xr-x 29 atmark atmark 4096 3月 6 15:58 include
drwxr-xr-x 2 atmark atmark 4096 4月 15 17:30 init
drwxr-xr-x 2 atmark atmark 4096 3月 24 11:22 ipc
drwxr-xr-x 14 atmark atmark 12288 5月 24 16:17 kernel
drwxr-xr-x 11 atmark atmark 20480 3月 24 11:22 lib
-rwxr-xr-x 2 atmark atmark 9543647 4月 15 17:30 linux
drwxr-xr-x 2 atmark atmark 12288 3月 24 11:22 mm
drwxr-xr-x 2 atmark atmark 4096 1月 23 2018 modules
-rw-r--r-- 1 atmark atmark 7285 4月 15 17:30 modules.builtin
-rw-r--r-- 1 atmark atmark 0 5月 24 16:25 modules.order
drwxr-xr-x 57 atmark atmark 4096 3月 24 11:22 net
drwxr-xr-x 12 atmark atmark 4096 11月 6 2017 samples
drwxr-xr-x 13 atmark atmark 4096 3月 24 10:54 scripts
drwxr-xr-x 9 atmark atmark 4096 3月 24 11:22 security
drwxr-xr-x 22 atmark atmark 4096 3月 24 18:56 sound
drwxr-xr-x 18 atmark atmark 4096 11月 6 2017 tools
drwxr-xr-x 2 atmark atmark 4096 3月 24 11:22 usr

と 2018/3/24 の日付がいくつかあるので、関連あるかと存じます。

> #ifdef HAS_RTC
> time_t bst = BUILD_START_UNIX;
> :

何かのファイルを見ているのであれば 2000/1/1 とかキリのいい日付で
固定化したいところです。
(touch コマンドでファイルの更新日時を強制的に更新するとか)

RTCやNTPでの時刻補正が正常に機能せずに 2018/3/24 でシステムが動き始めてしまうと
本来の日付なのかそうでないのかの判別が付きづらいので...

中村です。

> > #ifdef HAS_RTC
> > time_t bst = BUILD_START_UNIX;
> > :
>
> 何かのファイルを見ているのであれば 2000/1/1 とかキリのいい日付で
> 固定化したいところです。
> (touch コマンドでファイルの更新日時を強制的に更新するとか)

flatfsd-3.0.2/Makefileに次の行があり、
makeした現在時刻をBUILD_START_UNIXにセットしています。

# build start time in seconds
BUILD_START_STRING ?= $(shell date -R)
BUILD_START_UNIX   := $(shell date "-d$(BUILD_START_STRING)" +%s)
CFLAGS += -DBUILD_START_UNIX=$(BUILD_START_UNIX)

flatfsd.cからflatfsd.oを作るときのmakeで決定される時刻なので、
全体をビルドしなおしてもflatfsd.cが再コンパイルにならなければ、
以前のビルド(make)時の時刻がそのまま残ります。

一番てっとりばやいのは、ソースに手を入れて、
たとえば次のように、この部分を無効にしてしまうことです。

//#ifdef HAS_RTC
#if 0
        time_t bst = BUILD_START_UNIX;
 
        if (time(NULL) < bst) {
                stime(&bst);
        }
#endif

あるいは、Makefileに

ifdef CONFIG_USER_FLATFSD_HAS_RTC
CFLAGS += -DHAS_RTC
endif

とありますので、コンフィグレーションで
CONFIG_USER_FLATFSD_HAS_RTCをオフにするという方法もありますが、
flatfsdのソースディレクトリでHAS_RTCをgrepすると他にも使っている
ところがありますので、他の部分が大丈夫かどうか確認した方がいいです。

> RTCやNTPでの時刻補正が正常に機能せずに 2018/3/24 でシステムが動き始めてしまうと
> 本来の日付なのかそうでないのかの判別が付きづらいので...

なぜこんなことをしているのかわかりませんが、
これ、かなり迷惑なことだと思います。
RTCを昔の時刻に戻して再起動テストということもできなくなります。

RTCが接続されていないときは、1970/1/1 09:00:00 JST になるはずです。
RTCが接続されてバックアップされていないときは、
前に書いたようにS35390Aは 2000/1/1 09:00:00 JST になりますが、
お使いのRTCチップRX-8564がどうなるかはデータシートを見てください。
(ソースを修正して試してみるのが早いかも)

--
なかむら

中村です。

> あるいは、Makefileに
>

> ifdef CONFIG_USER_FLATFSD_HAS_RTC
> CFLAGS += -DHAS_RTC
> endif
> 

> とありますので、コンフィグレーションで
> CONFIG_USER_FLATFSD_HAS_RTCをオフにするという方法もありますが、
> flatfsdのソースディレクトリでHAS_RTCをgrepすると他にも使っている
> ところがありますので、他の部分が大丈夫かどうか確認した方がいいです。

この「他の部分」に該当するかもしれない部分で、
昔、flatfsdで同じようなところを見ていた気がして、
探してみました。

5年も前の話なのでflatfsdのソースバージョンが違い、
原因も結果も今回とは違うのですが、RTCの有無が影響して、
「ブート時にinitから呼び出されてflatfsd -r したときに時計が
勝手に変更されてしまう」というおせっかいな仕様は、
昔のバージョンでもあったようです。

あまり参考にはならないと思いますが、リンクを貼っておきます。
http://lists.atmark-techno.com/pipermail/armadillo/2013-May/008877.html
http://lists.atmark-techno.com/pipermail/armadillo/2013-June/008889.html

--
なかむら

中村様

長島です。お世話になっております。

いろいろとご調査頂き、誠に有難うございます。

今思いついたのですが、目的が
 「RTCもNTPもNGだったときには 2000/1/1 など区切りのいい日付にしたい」
なので、OSのソースを直さずに

0. /etc/config/rc.local で "date 0101000000" を実行(date [MMDDhhmmYY]) <== 追加
1. RTCの時刻をシステムクロックに反映
2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
3. システムクロックの時刻でRTCの時刻を補正

が一番早く確実な気がしますがいかがでしょうか?

中村です。

> 0. /etc/config/rc.local で "date 0101000000" を実行(date [MMDDhhmmYY]) <== 追加

これを常にやるとなると、

> 2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
> 3. システムクロックの時刻でRTCの時刻を補正

この3でRTCにセットしたNTPで補正した時刻は、
いつ使うのでしょうか?
3の後にshutdownするなどして電源OFFして、
次の起動時に0をやるなら、RTCはいらないですよね?
(RTCがあってもなくても同じ)

--
なかむら

中村様

長島です。お世話になっております。
レスが遅くなりまして、失礼いたしました。

> 中村です。
>
> > 0. /etc/config/rc.local で "date 0101000000" を実行(date [MMDDhhmmYY]) <== 追加
>
> これを常にやるとなると、
>
> > 2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
> > 3. システムクロックの時刻でRTCの時刻を補正
>
> この3でRTCにセットしたNTPで補正した時刻は、
> いつ使うのでしょうか?
> 3の後にshutdownするなどして電源OFFして、
> 次の起動時に0をやるなら、RTCはいらないですよね?
> (RTCがあってもなくても同じ)

0. /etc/config/rc.local で "date 0101000000" を実行
1. RTCの時刻をシステムクロックに反映
2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
3. システムクロックの時刻でRTCの時刻を補正

なので、
 ・RTC:OK、NTP:OK => NTPの時刻で稼働
 ・RTC:NG、NTP:OK => NTPの時刻で稼働
 ・RTC:OK、NTP:NG => RTCの時刻で稼働
 ・RTC:NG、NTP:NG => 2000/1/1 0:00 [UTC] で稼働
になるかと。

現在のターゲット製品が離島などN/W接続が不安定な環境で使われるため、
割とRTCの出番が多くなることを想定しております。

中村です。

> 0. /etc/config/rc.local で "date 0101000000" を実行
> 1. RTCの時刻をシステムクロックに反映
> 2. NTPサーバに時刻問い合わせを行い、システムクロックに反映
> 3. システムクロックの時刻でRTCの時刻を補正
>
> なので、
>  ・RTC:OK、NTP:OK => NTPの時刻で稼働
>  ・RTC:NG、NTP:OK => NTPの時刻で稼働
>  ・RTC:OK、NTP:NG => RTCの時刻で稼働
>  ・RTC:NG、NTP:NG => 2000/1/1 0:00 [UTC] で稼働
> になるかと。

の1は、無条件ではなく、
 RTCにそれらしい時刻が設定されていたら、
ですね?

--
なかむら

長島です。お世話になっております。

> の1は、無条件ではなく、
>  RTCにそれらしい時刻が設定されていたら、
> ですね?

処理としては良くないですが、現在は無条件に実行しています。
(その後のNTPでも補正されるため)

「それらしい時刻が設定されていたら」をどう判定するかも悩んでます。
使用しているチップ(RTC-8564)はバッテリバックアップが一定基準を下回ると
Low Voltage フラグが立つので、このときは「RTCの時刻をシステムクロックに反映」の
処理がエラーになるので、結果的に反映されません。

現在まだ検証中なのですが、バッテリが少なくなってきて、まだLow Voltage フラグが立っていない状態でも
RTCの値が不安定になるケースがあるようで、このときは過去日付になったり未来日付になったり。
過去日付のチェックは「2018/1/1より前は過去」とか決め打ちできるのですが ... 未来はどうしたものかと ^^;

中村です。

説明ありがとうございます。

> 処理としては良くないですが、現在は無条件に実行しています。

無条件に実行して常に
>> 1. RTCの時刻をシステムクロックに反映
となるのではなくて、

> 使用しているチップ(RTC-8564)はバッテリバックアップが一定基準を下回ると
> Low Voltage フラグが立つので、このときは「RTCの時刻をシステムクロックに反映」の
> 処理がエラーになるので、結果的に反映されません。

無条件に実行して、エラーにならなければ
>> 1. RTCの時刻をシステムクロックに反映
ということですね。

> 現在まだ検証中なのですが、バッテリが少なくなってきて、まだLow Voltage フラグが立っていない状態でも
> RTCの値が不安定になるケースがあるようで、このときは過去日付になったり未来日付になったり。

これは対応が大変そう。

--
なかむら

中村です。

2つ前の自分の投稿、
> 次の起動時に0をやるなら、RTCはいらないですよね?
> (RTCがあってもなくても同じ)

読み直したら、そんなことはないですね。
間違いを書いていました。すみません。
訂正しておきます。

--
なかむら