ARM40-A5应用——与网络时间的同步

ARM40-A5应用——与网络时间的同步

2018.6.28
版权声明:本文为博主原创文章,允许转载。

  ARM40部署提要:
  (1)根据7.1节(1)(2)(3)(4)(5)(6)的步骤建立各个文件;
  (2)按7.3节测试;

  本文介绍ARM40-A5本地系统时间与网络时间同步的方法,共介绍了三种方式: ntpdate、ntpd、rdate。
  内容较多,读者可跳至第七节“总结”部分使用推荐的方式。

一、8025T 时钟芯片简介

  ARM40-A5采用8025T 给主板提供本地实时时钟。8025T实时时钟芯片具有极低的功耗,内置高稳定度的32.768kHz的晶体,并自带温度补偿功能。在电表、水表、燃气表,工业控制,门禁,安防等领域得到广泛的应用。

二、时区

  (1)显示系统的日期与时间
root@ARM40:~# date // 显示系统的日期与时间,默认显示UTC时间
Thu Jun 28 01:01:31 UTC 2018
  date命令默认是显示UTC时间。UTC为0时区的时间,即协调世界时(Universal Time Coordinated)。对应的,北京的时区为东八区,即CST 时间(或CST-8时间)。北京为早上八点(东八区)时,UTC时间为零点,时间比北京时间晚八小时。
  (2)显示北京时间
  如果要显示北京时间呢?命令如下:
root@ARM40:/etc/ppp# TZ=CST-8 date // 仅本次,显示CST-8时区的系统日期与时间
Thu Jun 28 09:01:33 CST 2018 // 可见,北京时间比UTC时间早8小时
  (3)默认即显示北京时间
  如果我们希望date命令默认不是显示UTC时间,而是默认显示CST-8时间呢?
  在/etc/profile 中增加:
export TZ='CST-8'
  修改后,我们测试一下看看:
root@ARM40:~# source /etc/profile
root@ARM40:~# date
Thu Jun 28 09:19:20 CST 2018 // 可见,date命令已默认显示北京时间
  在date命令默认显示北京时间的情况下,如果我们想看看UTC时间呢?
root@ARM40:~# date -u
Thu Jun 28 01:19:22 UTC 2018

三、CMOS时间

  (1)显示CMOS时间
  ARM40-A5采用8025T 给主板提供本地实时时钟,其概念类似于电脑上的CMOS时间。8025T中默认应存储UTC时间。
root@ARM40:~# date -u
Thu Jun 28 01:55:14 UTC 2018
root@ARM40:~# hwclock // 显示8025T存储的时间,hwclock显示的是UTC时间
Thu Jun 28 01:55:14 2018 0.000000 seconds
  上面的两行测试,也可能因为8025T保存的时间原本就不准确,而出现date时间与hwclock时间不一致的情况。此时需要校准8025T中的时间。
  (2)校准CMOS时间
  如果8025T保存的时间不够准确,则需要校时,命令如下:
root@ARM40:~# export TZ=CST-8 // 临时设置为CST-8 时区
root@ARM40:~# date 062513272018.00 // 设置为 2018-06-25-13:27:00,若设置距离当前时间较远的时间,系统可能会拒绝
Mon Jun 25 13:27:00 CST 2018
root@ARM40:~# date -u // 以UTC时区显示系统的日期与时间
Mon Jun 25 05:27:00 UTC 2018
root@ARM40:~# hwclock -w --utc // 将date时间对应的UTC时间存入8025T中
root@ARM40:~# hwclock // 显示8025T存储的时间,hwclock显示的是UTC时间
Mon Jun 25 05:27:12 2018 0.000000 seconds
  测试:
  在8025T的电池存在的情况下,给ARM40-A5断电,过几分钟后,再次上电。
  因为上电时会运行 /etc/profile 中的 export TZ=’CST-8’ 的,所以上电后date默认显示的是CST-8 时间。
root@ARM40:~# date // 显示系统的日期与时间,此时默认显示CST-8时间
Mon Jun 25 21:33:10 CST 2018 // 对应的UTC时间为 Jun 25 13:33:10
root@ARM40:~# date -u
Mon Jun 25 13:33:12 UTC 2018
root@ARM40:~# hwclock // 显示8025T存储的时间,hwclock显示的是UTC时间
Mon Jun 25 13:33:20 2018 0.000000 seconds

四、使用ntpdate与网络时间同步

  为了避免主机时间因为长期运作下所导致的时间偏差,进行时间同步(synchronize)的工作是非常必要的。
  (1)从时间服务器获取网络时间并同步
  例1:(ARM40-A5位于内网的情况)

killall ntpd                                  // ntpd与ntpdate冲突,需要kill掉
ifconfig eth0 192.168.1.5                     // 这个例子是内网的情况
route add default gw 192.168.1.1
ntpdate 120.25.108.11                         // 时间服务器1,阿里云提供
ntpdate 182.92.12.11                          // 时间服务器2,阿里云提供
ntpdate cn.pool.ntp.org                       // 时间服务器3,需要DNS

  例2:(ARM40-A5使用4G、GPRS联网的情况)
    《ARM40-A5应用——GPRS模块ppp拨号上网》
    《ARM40-A5应用——4G模块EC20-CE拨号上网》

killall ntpd                                  // ntpd与ntpdate冲突,需要kill掉
ntpdate 120.25.108.11                         // 时间服务器1,阿里云提供
    // 28 Jun 11:15:44 ntpdate[22335]: adjust time server 120.25.108.11 offset 0.289128 sec
ntpdate 182.92.12.11                          // 时间服务器2,阿里云提供
    // 28 Jun 11:16:15 ntpdate[22353]: adjust time server 182.92.12.11 offset 0.234394 sec
ntpdate cn.pool.ntp.org                       // 时间服务器3,需要DNS
    // 28 Jun 11:15:05 ntpdate[22321]: step time server 85.199.214.101 offset 247081.637253 sec

  时间同步完毕后,用 date 命令观察显示的时间是否与手机上此刻的时间相同,相同则表示同步成功:
root@ARM40:~# date
Thu Jun 28 11:25:18 CST 2018

  (2)定期与网络时间同步
  一般配合crontab 命令,来进行定期同步设置。比如,在 crontab -e 中添加:
root@ARM40:~# crontab -e // 编辑 crontab 的内容:定期与网络时间同步
*/30 * * * * (ntpdate 120.25.108.11) && (hwclock -w --utc) >/dev/null 2>&1
  这样,每30分钟,同步一次时间。ntp服务器为120.25.108.11。其中的 hwclock -w –utc 是更新后把时间写入CMOS。
root@ARM40:/# crontab -l // 查看 crontab 的内容
*/30 * * * * (ntpdate 120.25.108.11) && (hwclock -w --utc) >/dev/null 2>&1
  在开发和测试阶段,每30分钟同步一次时间,这样测试需要等太久,下面提供两个测试用例。
  ① 首先查看ps,kill 掉 crond 和之前的crontab工作排程。
  ② 修改 crontab -e 的内容后,重新crond。
  下面是修改 crontab -e 内容的示例:
root@ARM40:~# crontab -e // 编辑 crontab 的内容:测试每1分钟同步一次
* * * * * * (ntpdate 120.25.108.11) && (hwclock -w --utc) >/dev/null 2>&1
root@ARM40:/# crontab -e // 编辑 crontab 的内容:测试每1分钟给 /dev/ttyS0 发一个字符串
* * * * * echo "Good morning" >> /dev/ttyS0


  注意:利用crond服务实现NTP定时同步可能出现的问题
  (1)crontab -e 时可能会出现下面的提示:
crontab: can't change directory to '/var/spool/cron/crontabs': No such file or directory
  此时需要建立相应的文件:
root@ARM40:~# mkdir -p /var/spool/cron/crontabs
  (2)crontab -e 设置好同步时间后,需要打开 crond 服务:
root@ARM40:~# crond
  ps 可以看到 crond 服务已开启。


  (3)上电自启动crontab排程
  如果要每次开机启动后都会自动运行这些工作,则
  ① 建立 /etc/cron.arm40 文件,内容为:
*/30 * * * * (ntpdate 120.25.108.11) && (hwclock -w --utc) >/dev/null 2>&1
  ② 在 /etc/profile 文件中加上:

killall ntpd
mkdir -p /var/spool/cron/crontabs
crontab /etc/cron.arm40
crond

  这样,每次开机启动后都会开启排程,并且在每30分钟都会同步一次时间。

五、使用ntpd与网络时间同步

  使用ntpd服务,要好于ntpdate加crontab的组合。因为,ntpdate同步时间,会造成时间的跳跃,对一些依赖时间的程序和服务会造成影响。比如sleep,timer等。而且,ntpd服务可以在修正时间的同时,修正cpu tick。理想的做法为,在开机的时候,使用ntpdate强制同步时间,在其他时候使用ntpd服务来同步时间。
  要注意的是,ntpd 有一个自我保护设置:如果本机与上源时间相差太大,ntpd 不运行。所以新设置的时间服务器一定要先 ntpdate 从上源取得时间初值,然后启动 ntpd 服务。ntpd服务运行后,先是每64秒与上源服务器同步一次,根据每次同步时测得的误差值经复杂计算逐步调整自己的时间,随着误差减小,逐步增加同步的间隔。每次跳动,都会重复这个调整的过程。

root@ARM40:~# /etc/init.d/S49ntp restart
Restarting ntpd: 
Stopping ntpd: FAIL
Starting ntpd: OK

  查看端口:
root@ARM40:~# netstat -ln | grep 123

  使用 ntpq -p 查询网络中的NTP服务器,同时显示客户端和每个服务器的关系。在这之前,可能需要设置DNS。
echo "nameserver 223.5.5.5" > /etc/resolv.conf
echo "nameserver 223.6.6.6" >> /etc/resolv.conf
  然后 ntpq -p 查询NTP服务器,当然,不查询也没任何问题。

六、使用rdate与网络时间同步

  (1)使用rdate与网络时间同步
  由于ntp协议容易受到攻击,很多机房都限制了该协议,或者直接封掉123端口,可以使用rdate命令来同步时间。rdate 使用tcp协议,端口37。
  rdate命令用于显示其他主机的日期与时间。执行rdate指令,向其它主机询问系统时间并显示出来。
  语法
    rdate [-ps][主机名称或IP地址…]
  参数:
    -p 显示远端主机的日期与时间。
    -s 把从远端主机收到的日期和时间,回存到本地主机的系统时间。

  实作如下:

root@ARM40:/etc# rdate -p time.nist.gov
Thu Jun 28 10:47:03 2018                                            // 显示的是UTC时间
root@ARM40:/etc# export TZ=CST-8
root@ARM40:/etc# rdate -p time.nist.gov
Thu Jun 28 18:47:27 2018                                            // 显示的是CST-8时间
root@ARM40:/etc# rdate -p 129.6.15.28
Thu Jun 28 19:01:12 2018
root@ARM40:/etc# rdate -s 129.6.15.28
root@ARM40:/etc# date
Thu Jun 28 19:01:15 2018
root@ARM40:/etc# rdate -s time-b.nist.gov
root@ARM40:/etc# date
Thu Jun 28 18:47:30 2018                                            // 显示的是CST-8时间

  (2)部署一套自己的 rdate 时间服务器
  在Linux服务器上启动时钟服务
#chkconfig time on
  如果不启动这个服务,在client运行rdate同步时间时会报错的:
rdate: couldn’t connect to host 192.168.2.31: Connection refused

七、总结

  更新时间的方式较多,这里给出推荐的ARM40-A5与网络时间同步的方式。

7.1、推荐的网络时间同步方式

  (1)要有网。
  ARM40-A5与网络时间同步,当然要有网。如果是4G或GPRS联网方式可参考《ARM40-A5应用——GPRS模块ppp拨号上网》《ARM40-A5应用——4G模块EC20-CE拨号上网》。
  
  (2)建立/opt/user/date_update.sh文件,
  touch /opt/user/date_update.sh
  chmod 755 /opt/user/date_update.sh
  其内容为:

#!/bin/sh

hwclock -s                  # Set system time from hardware clock

#echo "nameserver 223.5.5.5" > /etc/resolv.conf    # aliyun DNS1
#echo "nameserver 223.6.6.6" >> /etc/resolv.conf   # aliyun DNS2
ntpServer="129.6.15.28"

while true                        # when startup,update date
do
        sleep 60
        rdate -s $ntpServer
        tmp=$?
        #echo $tmp                                 # for test
        if [ $tmp -eq 0 ]; then                    # get ntp time
                hwclock -w
                echo "Date is updated."
                exit 0
        else                                       # can't get ntp time
                procnum=`ps -ef|grep "rdate"|grep -v grep|wc -l`
                if [ $procnum -ne 0 ]; then
                        killall rdate
                fi
        fi
done

  简单介绍 /opt/user/date_update.sh 文件的功能:
  系统启动后,首先将硬件时间设置为系统时间,即hwclock -s,然后 rdate -s $ntpServer 获取服务器的网络时间,如果成功,则 hwclock -w保存 hardware clock 时间,然后退出。如果未能获取网络时间,则等待60s后继续获取。

  (3) 建立 /opt/user/cron_user.sh 文件,
touch /opt/user/cron_user.sh
chmod 755 /opt/user/cron_user.sh
  其内容为:

#!/bin/sh

if [ ! -d /var/spool/cron/crontabs ]; then
        mkdir -p /var/spool/cron/crontabs
fi
crontab /etc/cron.arm40         # cron
crond

  (4) 建立 /etc/cron.arm40 文件,增加一行:
0 1 * * * (rdate -s 129.6.15.28) && (hwclock -w) &>/dev/null 2>&1
  每天的凌晨1点 rdate 从时间服务器获取网络时间,更新系统时间,并存入到 hardware clock 中。

  (5)修改 /etc/inittab 文件
  修改 /etc/inittab中的
console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
#console::respawn:-/bin/sh
  为:
#console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
console::respawn:-/bin/sh

  (6)修改 /etc/profile 文件(在最后添加)

reset
export TZ='CST-8'                 # CST-8, Beijing time

logintty=$(tty|grep -c "console")
if [ $logintty -eq 1 ]; then            # ssh,telnet can't get into this line
        /opt/user/date_update.sh &      # when startup,update date
        /opt/user/cron_user.sh &        #cron
fi

  修改完毕后 source /etc/profile 使 /etc/profile 的设置生效;或者 reboot 重启ARM40-A5,观察程序运行的情况。

  7.2、解读
  (1)ARM40-A5上电后,默认会启动 ntpd 服务校准系统时间,该服务每64s校时一次。
  命令 ps 可看到ntpd服务 /usr/sbin/ntpd -g ,命令 ntpq -p 可以看到校时情况。
  ntpd在本地系统时间与服务器时间差别较大时(1000s),则不会继续更新系统时间了。因此,增加下面的两个措施。
  (2)在上电启动时,同步一次网络时间;
  刚上电时,可能本地系统时间与服务器时间差别较大,故同步一次。
  由 /opt/user/date_update.sh 文件完成上电时的同步功能,每60s同步一次,直到成功后退出。
  另建议在设备安装启用时,检查系统时间是否同步成功,一般在5分钟内,就会同步成功。
  (3)在每天的凌晨1点,与时间服务器同步一次。
  若出现意外故障,或人为误操作,可能导致本地系统时间与服务器时间差别较大,故每天同步一次系统时间与 hardware clock 时间。

  7.3、测试建议
  测试阶段往往需要反复操作,如修改 /etc/cron.arm40、/opt/user/date_update.sh、/etc/profile 等,尝试各种情况。这时可能需要杀死之前的进程或服务,并重新使能。
  killall crond # 删除服务
  crontab -r # 删去排程
  source /etc/profile # 使 /etc/profile 的设置生效
  测试阶段还可能需要调整系统时间,观察程序是否成功校正了系统时间。
  date 062513272018.00 # 设置系统时间为 2018-06-25-13:27:00

八、常见问题

  (1)时间服务器
  在NTP官方网站可找到提供同步服务的NTP SERVER,当然也可以自己搭建NTP服务器。NTP官网地址: http://www.pool.ntp.org/en/
  (2)rdate时间服务器
  更多的rdate时间服务器见 https://tf.nist.gov/tf-cgi/servers.cgi
  (3)rdate -s $ntpServer 同步网络时间可能出现的情况:

# rdate -s 129.6.15.28
rdate: current time matches remote time              # 同步成功,返回值为0
# rdate -s 129.6.15.28
rdate: timeout connecting to time server             # 超时,返回值为1
# rdate -s 129.6.15.28
rdate: can't connect to remote host (129.6.15.28): Network is unreachable    # 无法联网,返回值为1
# rdate -s time.nist.gov
rdate: bad address 'time.nist.gov'                   # DNS error,返回值为1
# rdate -s 129.6.15.28
rdate: 129.6.15.28: short read                       # 其它错误,返回值为1

参考文章:

  date命令 http://man.linuxde.net/date
  ntpdate命令 http://man.linuxde.net/ntpdate
  《ARM40-A5应用——GPRS模块ppp拨号上网》
  《ARM40-A5应用——4G模块EC20-CE拨号上网》
  NIST Internet Time Servers https://tf.nist.gov/tf-cgi/servers.cgi
  在NTP官方网站官网地址: http://www.pool.ntp.org/en/
  《鳥哥的 Linux 私房菜》第十五章、時間伺服器: NTP 伺服器
  http://linux.vbird.org/linux_server/0440ntp.php
  crontab 定时任务
  http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html
  crontab命令进程和作业管理
  http://man.linuxde.net/crontab
  阿里云服务器/etc/crontab文件
  荟聚计划:共商 共建 共享 Grant

猜你喜欢

转载自blog.csdn.net/vonchn/article/details/81940748