linux时间之hwclock

·  阅读 183

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

今天说说 hwclock 这个工具,估计也就玩物联网的朋友会用到了,因为这个工具往往只是用来保持硬件设备的时间的,但是前大多数设备往往都是联网的,也就是用的 NTP。

另外,Ubuntu 15.04 之后就用 systemd 来管理时间了,它里面自带的 timedatectl 工具取代了 hwclock,不过本质上是差不多的内容,这里就不多说了。

介绍

当设备无法联网的时候,RTC 就会变得非常重要,系统的时间将会依靠纽扣电池的能量来维持。如果设备需要经常开关机,那么就会更加依赖 RTC 来保持设备时间的同步。

它的原理很简单,就是用纽扣电池驱动 RTC(Real-Time Clock)芯片来保持设备断电时候的时间,这样当设备重启的时候,就能直接从 RTC 恢复时间了。

首先让我们来看看 hwclock 的帮助信息:

Usage:
 hwclock [function] [option...]

Time clocks utility.

Functions:
 -r, --show           display the RTC time
     --get            display drift corrected RTC time
     --set            set the RTC according to --date
 -s, --hctosys        set the system time from the RTC
 -w, --systohc        set the RTC from the system time
     --systz          send timescale configurations to the kernel
 -a, --adjust         adjust the RTC to account for systematic drift
     --predict        predict the drifted RTC time according to --date

Options:
 -u, --utc            the RTC timescale is UTC
 -l, --localtime      the RTC timescale is Local
 -f, --rtc <file>     use an alternate file to /dev/rtc0
     --directisa      use the ISA bus instead of /dev/rtc0 access
     --date <time>    date/time input for --set and --predict
     --delay <sec>    delay used when set new RTC time
     --update-drift   update the RTC drift factor
     --noadjfile      do not use /etc/adjtime
     --adjfile <file> use an alternate file to /etc/adjtime
     --test           dry run; implies --verbose
 -v, --verbose        display more details

 -h, --help           display this help
 -V, --version        display version
复制代码

下面来说说,如何使用这个命令来解决我们常见的两个问题。

时间同步

首先要分清两个时间,一个是硬件时间,也就是在 RTC 等硬件芯片中的时间,另一个是系统时间,也就是系统内核中的时间。

为了同步时间,用到它的两个参数就够了:

  1. 在关机前,将时间从系统写入 RTC:hwclock --systohc
  2. 在开机时,将时间从 RTC 写回系统:hwclock --hctosys

其实这步做完就可以完成离线状态下的时间同步了。设备能够在大多数情况下,达到设备时间保持与真实时间同步。

但,如果设备的时间精确性很重要,那么你就需要用到它的矫正功能了。

误差矫正

其实 RTC 的工作依赖于一块 32.768kHz 的晶振,也就是一块石英晶体,然而,石英晶体是不稳定的,尤其在温度变化的时候,就会变得有误差,这个误差每天可以达到一秒或更多。

RTC 受温度影响的误差

上图来自,可以从图中看到,温度过低或者过高都会导致偏差增大,而我们的设备一般是无法放在一个恒温环境下的,于是每天必然造成误差。

如何矫正这个误差呢?有硬件方案,也有软件方案。

硬件方案,德州仪器公司给了一个方案,可以直接用温度传感器来补偿 RTC 的精度,由于对硬件这块儿不熟悉,也说不出个所以然,只是明显的,硬件成本会增加一些。

软件方案就会朴实很多,因为我们可以假设这个设备所处的环境不变,硬件时间与系统时间的偏差是系统性的,简单点说,就是每隔一段固定的,它们之间时间的偏差其实是一致的。于是,我们用软件工程的角度来低成本地校准,也就是 hwclock 的校准功能。

它会用到一个文件 adjfile,用来记录校准的状态,不过先需要解释下 adjfile 的格式,它默认是 /etc/adjtime,它的内容包含 3 行文本:

  • 第一行,包含三个值:

    • 系统时间每天偏移量(秒)
    • 上次调整时间(Unix 时间戳)
    • 校正状态
  • 第二行:上次校准时间(Unix 时间戳)

  • 第三行:"UTC" 或者 "LOCAL"(一般只会用 UTC,别用 LOCAL 给自己添堵)

校准的用法也非常简单:

不过在开始之前,首先你需要确认 Linux 内核没有激活自动同步系统时间到硬件时间,不然会被 NTP 的 11 分钟模式 自动同步。具体就是运行 adjtimex --print 或者 adjtimex,看它的 status 值,看看有没有 UNSYNC,有就是不同步,或者需要自己计算下 status & 0x40,为 1 表示不同步

  1. (如果自动同步是激活状态)关闭且禁用 ntp 后台进程,且不会随系统启动;
  2. 手动同步一次系统时间;
  3. 同步系统时间至 RTC:hwclock --systohc,这时候,/etc/adjtime 里面的时间戳将会更新,但是偏移量为 0;
  4. 关机,等待至少一天;
  5. 开机,然后马上手动同步一次系统时间,然后让 hwclock 同步到 RTC 的同时,自动计算偏差 hwclock --systohc --update-drift
  6. 查看以及确认/etc/adjtime 里面的偏移量;
  7. (如果自动同步是激活状态)启动且启用 ntp 后台进程
分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改