http://fzhenyu.blog.163.com/blog/static/3094959720139248582630/
一、 基本概念
一般嵌入式系统至少有两个时间。一个是linux系统时间,另外一个是片内芯片时间(比如at91sam9x系列的芯片中含有rtc时钟)。前者可以说是软件的,后者是物理的、硬件的。然而一般片内的rtc不准确,硬件工程师往往会在硬件中加入一个比较精准的时钟芯片作为系统的精确时钟源(比如8025t,ds1302)。为了方便说明,现将上诉三个时钟暂依次称为系统时间、RTC时间、时钟芯片时间。
二、 时钟配置
① 系统时间
系统时间就是我们linux起来后,输入date可以看到的时间。比如:
/etc/sysconfig # date
Thu Oct 24 11:00:28 CST 2013
其中CST为中国的时间区间,东八区。其实默认arm下一般为UTC时间,如何改成中国时间区域百度很容易找到。(Asia/Shanghai 文件拷贝到/etc/localtime)
② RTC时间
RTC时间就是linux起来后,输入hwclock来操作的时钟。在裁剪内核的时候就是make muneconfig界面下有个选项是
Device Drivers——Real Time Clock下面的选项中,有一项是
Set system time from RTC on startup and resume勾选后,系统每次起来都会读取RTC时间后写到系统时间中。
除了上诉和系统时间的关系外,另外要重点说明hwclock命令操作的时区的相关问题。
输入hwclock –help可以看到
BusyBox v1.18.5 (2012-09-18 14:32:26 CST) multi-call binary.
Usage: hwclock [-r|--show] [-s|--hctosys] [-w|--systohc] [-l|--localtime] [-u|--utc] [-f FILE]
Query and set hardware clock (RTC)
Options:
-r Show hardware clock time
-s Set system time from hardware clock
-w Set hardware clock to system time
-u Hardware clock is in UTC
-l Hardware clock is in local time
-f FILE Use specified device (e.g. /dev/rtc2)
hwclock –w 就是写系统时间到RTC时间。
hwclock –s 就是写RTC时间到系统时间。
另外重点是在-u 和 -l 参数
hwclock –w –u //就是用当前的时间以UTC形式写入。比如上面的提到的时间是2013-10-24 11:00:28
那么再用hwclock –u来看RTC时间就是2013-10-24 11:00:28
而hwclock来看(默认-l)RTC时间就是相差了8个小时。网上有篇文章认为此时这个时间是无效的了,这里我也搞不清楚为什么是少了8个小时而不是多8个小时。但这个时间应该是有效的(下文会提到),只是逻辑上未能理解过来。
hwclock –w (默认-l) //就是以本地时间写入。
这里为止已经说清楚系统时间和RTC时间了,但是时区问题还未完全说明白。为了说清楚这个问题,接下去要提到系统中的一个配置文件/etc/sysconfig/clock 其内容如下
ZONE="Asia/Shanghai"
UTC=false
ARC=false
正常系统起来的时候会先调用脚本/etc/rc.sysinit,其中有段脚本就是关于时区设置的和UTC=false这个参数有关。arm如果没有这个脚本可以看看上位机中一定有,然后可以手动复制脚本到arm下的开机启动的第一个脚本中。
那么这个时候就要对应了
hwclock –w 且clock中的UTC=false的时候,系统重启后系统时钟就是正确的。
hwclock –w –u 且clock中的UTC=true的时候,系统重启后系统时钟也是正确的。
如果两者参数没对应,那么系统时间可能会相差8个小时。
③ 时钟芯片时间
这个比价好理解,是额外的时钟芯片需要有驱动的,一般在应用层,调用API接口来操作这个芯片,然后服务自己的系统时间。
三、 总结
时区这里说有点啰嗦了,总结一下我的配置,将UTC配置为CST时区。
1. 将上位机中正确的localtime拷贝到arm下的/etc/下。
2. 增加时钟配置文件,手动添加文件/etc/sysconfig/clock内容如下
ZONE="Asia/Shanghai"
UTC=false
ARC=false
3. 在开机启动脚本的开头加入
0;" > # Set the system clock.
ARC=0
SRM=0
UTC=0
if [ -f /etc/sysconfig/clock ]; then
. /etc/sysconfig/clock
# convert old style clock config to new values
if [ "${CLOCKMODE}" = "GMT" ]; then
UTC=true
elif [ "${CLOCKMODE}" = "ARC" ]; then
ARC=true
fi
fi
CLOCKDEF=""
CLOCKFLAGS="$CLOCKFLAGS --hctosys"
case "$UTC" in
yes|true) CLOCKFLAGS="$CLOCKFLAGS --utc"
CLOCKDEF="$CLOCKDEF (utc)" ;;
no|false) CLOCKFLAGS="$CLOCKFLAGS --localtime"
CLOCKDEF="$CLOCKDEF (localtime)" ;;
esac
case "$ARC" in
yes|true) CLOCKFLAGS="$CLOCKFLAGS --arc"
CLOCKDEF="$CLOCKDEF (arc)" ;;
esac
case "$SRM" in
yes|true) CLOCKFLAGS="$CLOCKFLAGS --srm"
CLOCKDEF="$CLOCKDEF (srm)" ;;
esac
/sbin/hwclock $CLOCKFLAGS
act
4. 每次修改系统时间后用命令再用hwclock –w 写入到硬件RTC时间。如果有时钟芯片可以再写入到时钟芯片中。