Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1140428
  • 博文数量: 322
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 3276
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-17 09:21
文章分类

全部博文(322)

文章存档

2010年(155)

2009年(167)

我的朋友

分类: 嵌入式

2010-01-15 11:08:23

之前对Linux下面时间相关的内容,一无所知,第一次见到hwclock,不知为何物,也没找到解释清楚的帖子。故此整理一下,简单介绍Linux下验证rtc驱动是否工作正常,相关的的命令:date和hwclock。
先说明:
1.本贴主要内容来整理自后注所引用的帖子。
2.如下介绍,不涉及如何编写rtc驱动,只简单介绍,驱动实现后,如果通过date和hwclock去验证rtc驱动是否正常工作。
【基础知识】
1.date,Linux中用于显示/修改系统时间的一个命令。

使用格式:

date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]

date 可以用来显示或设定系统的日期与时间。

1.在显示方面,使用者可以设定欲显示的格式,格式设定为一个加号后接数个标记,其中可用的标记列表如下:

时间方面 :

% :  打印出 %
%n : 下一行
%t : 跳格
%H : 小时(00..23)
%I : 小时(01..12)
%k : 小时(0..23)
%l : 小时(1..12)
%M : 分钟(00..59)
%p : 显示本地 AM 或 PM
%r : 直接显示时间 (12 小时制,格式为 hh:mm:ss [AP]M)
%s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
%S : 秒(00..61)
%T : 直接显示时间 (24 小时制)
%X : 相当于 %H:%M:%S
%Z : 显示时区

日期方面 :

%a : 星期几 (Sun ..Sat)
%A : 星期几 (Sunday..Saturday)
%b : 月份 (Jan..Dec)
%B : 月份 (January..December)
%c : 直接显示日期与时间
%d : 日 (01..31)
%D : 直接显示日期 (mm/dd/yy)
%h : 同 %b
%j : 一年中的第几天 (001..366)
%m : 月份 (01..12)
%U : 一年中的第几周 (00..53) (以 Sunday 为一周的第一天的情形)
%w : 一周中的第几天 (0..6)
%W : 一年中的第几周 (00..53) (以 Monday 为一周的第一天的情形)
%x : 直接显示日期 (mm/dd/yy)
%y : 年份的最后两位数字 (00.99)
%Y : 完整年份 (0000..9999)

2.在设定时间方面

date -s //设置 当前时间,只有root权限才能设置,其他只能查看。
date -s 20080523 //设置成20080523,这样会把具体时间设置成空00:00:00
date -s 01:01:01 //设置具体时间,不会对日期做更改
date -s “01:01:01 2008-05-23″ //这样可以设置全部时间
date -s “01:01:01 20080523″ //这样可以设置全部时间
date -s “2008-05-23 01:01:01″ //这样可以设置全部时间
date -s “20080523 01:01:01″ //这样可以设置全部时间

3.加减

date +%Y%m%d         //显示前天年月日
date +%Y%m%d --date="+1 day"  //显示前一天的日期
date +%Y%m%d --date="-1 day"  //显示后一天的日期
date +%Y%m%d --date="-1 month"  //显示上一月的日期
date +%Y%m%d --date="+1 month"  //显示下一月的日期
date +%Y%m%d --date="-1 year"  //显示前一年的日期
date +%Y%m%d --date="+1 year"  //显示下一年的日期


2.Linux的RTC驱动

从启动信息可以看出没有加载成功RTC驱动!

 

TCP cubic registered

NET: Registered protocol family 1

RPC: Registered udp transport module.

RPC: Registered tcp transport module.

drivers/rtc/hctosys.c: unable to open rtc device (rtc0)

IP-Config: Complete:

      device=eth0, addr=192.168.0.69, mask=255.255.255.0, gw=192.168.0.1,

     host=www, domain=, nis-domain=kevin.com,

     bootserver=192.168.0.104, rootserver=192.168.0.104, rootpath=

Looking up port of RPC 100003/2 on 192.168.0.104

S3C2410RTC已经在2.6.24.4 kernel中,但是没有加入SMDK2410 targetboard

所以我们只需要将RTC加入初始化的设备列表中。

 

1.       menu configRTC部分使用默认设置。

2.       修改文件mach-smdk2410.c/linux2.6.24.4/arch/arm/mach-s3c2410/mach-smdk2410.c),在数组smdk2410_devices[]中添加&s3c_device_rtc.

3.       /dev目录下创建rtc设备文件rtc.

            mknod rtc c 10 135

4.       重新编译内核。看看启动信息。

            ……

            S3C24XX RTC, (c) 2004,2006 Simtec Electronics

            s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling

            s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0

            ……

 

            以上信息说明RTC设备已经加入内核了。

            ……

            s3c2410-rtc s3c2410-rtc: hctosys: invalid date/time

            ……

 

            以上信息说明可能还没有设置RTC时间,RTC初始时间为 Wed Dec 31 23:59:59 1969。从内核函数int rtc_valid_tm(struct rtc_time *tm),可以看出,当year小于1970时,认为是时间 invalid,函数返回-EINVAL,下面来验证一下这个想法。

[root@DaiQ /]# hwclock

 Wed Dec 31 23:59:59 1969  0.000000 seconds

 [root@DaiQ /]# date

 Thu Jan  1 00:06:58 UTC 1970

 

系统时间是通过date来设置的,RTC时间是通过hwclock来设置的。开机时系统时间首先通过RTC来获得,RTC没有设置时,系统时间也会使用Wed Dec 31 23:59:59 1969。

实现完了后,一般是默认的是一个普通的字符型设备,或者一个misc设备,也可以是一个平台设备。
对应地,如果insomod驱动后,或者build-in到kernel后,对应的设备一般是
/dev/rtc 或 /dev/rtc0 或者 /dev/misc/rtc
3.hwclock,见名知意,hw clock, hardware clock,硬件(RTC)时钟。
对于hwclock,看看具体什么用途和用法(此处是嵌入式开发中用到的用busybox中的hwclock):

# hwclock --help
BusyBox v1.13.4 (2009-09-18 16:05:03 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)


刚刚根据上面的解释,不知道别人如何,我是之前被-s和-w的解释搞晕了,也就后来用错了。。。。
所以,找了下,找到意思更清晰的,是man hwclock的解释,摘录相关部分如下:

hwclock -r or hwclock --show
hwclock -w or hwclock --systohc
hwclock -s or hwclock --hctosys
--show
Read the Hardware Clock and print the time on Standard Output......
--hctosys
Set the System Time from the Hardware Clock......
This is a good option to use in one of the system startup scripts.
--systohc
Set the Hardware Clock to the current System Time.


上面的解释就很清楚了,用中文解释为:
 

hwclock –r        show, 显示硬件时钟, 等价于不加参数的hwclock。
hwclock –s        hctosys,hardware clock to system, 将“硬件时钟”RTC的时间写到Linux“系统”时钟里。
hwclock –w        systohc,system to hardware clock ,将“系统”时钟写到“硬件时钟”RTC里面。


运行hwclock,会自动去寻找对应的rtc设备,然后执行对应的操作。
网上所找到的,busybox中的对应的代码如下:

static const char *rtcname;
static int xopen_rtc(int flags)
{
int rtc;
if (!rtcname) {
   rtc = open("/dev/rtc", flags);
   if (rtc >= 0)
    return rtc;
   rtc = open("/dev/rtc0", flags);
   if (rtc >= 0)
    return rtc;
   rtcname = "/dev/misc/rtc";
}
return xopen(rtcname, flags);
}

 
4. 在Linux中有硬件时钟与系统时钟等两种时钟。
硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟,对于嵌入式开发,对应开发板上有对应的rtc模块。
系统时钟则是指kernel中的时钟。当Linux启动时,系统时钟会去读取硬件时钟的设定,之后系统时钟即独立运作。
所有Linux相关指令与函数都是读取系统时钟的设定。系统时钟的设定就是我们常用的date命令。
而我们写的RTC驱动就是为硬件时钟服务的,它有属于自己的命令hwclock。
因此,可以简单理解为,date命令操作Linux的系统(软件)时钟,hwclock命令操作硬件时钟(rtc模块)。
所以,对应地,我们要验证rtc驱动是否工作正常,只需要hwclock,
但往往又会涉及Linux的系统时钟和硬件时钟之间的同步等操作,所以,一般都是将date和hwclock一起搭配使用。
【用date和hwclock测试rtc驱动工作是否正常】
一般来说,最简单的测试rtc是否工作正常的步骤就是,在加载完rtc驱动后(或者本身驱动是已经编译进内核的):
1.显示当前Linux系统时间

date


[2].如果date时间也不正常,比如是1970年之类的,而不是我当前的时间,比如2009年,那么就自己手动设置一下正确时间

date MMDDhhmm[[YY]YY][.ss]


3.显示硬件rtc时间

hwclock


由于此处是rtc驱动第一次加载,还没设置正确的时间,所以此时显示的时间,多数是不正确的是1969,1970年。
4.将Linux系统时间设置到硬件rtc中

hwclock -w


5.再次查看硬件rtc时间是否和系统中的一致

hwclock


如果驱动正确工作的话,此处显示的时间,就应该和你当前的系统时间一致了,也就是传说中的,时间同步了。。。
否则,就说明你驱动工作不正确,没有正确地把系统时间设置进入硬件rtc中,就要你自己回去调试驱动,找原因去。
6.等个几秒,再次输入:

hwclock


正常的话,会看到此处的时间,相对步骤5中显示的时间,增加了对应的那几秒
那就说明rtc正常工作了。
下面是我的示例:

# date
Wed Dec 31 17:01:25 MST 1969
//我这里此处系统时间也不正常,所以,下面去重新设置Linux系统时间

# date --help
BusyBox v1.13.4 (2009-09-18 16:05:03 CST) multi-call binary
Usage: date [OPTION]... [+FMT] [TIME]
Display time (using +FMT), or set time
Options:
        -u Work in UTC (don
't convert to local time)
        -R Output RFC-822 compliant date string
        -I[SPEC] Output ISO-8601 compliant date string
                        SPEC='
date
' (default) for date only,
                        '
hours', 'minutes', or 'seconds
' for date and
                        time to the indicated precision
        -d TIME Display TIME, not '
now


当然,知道了具体用法后,你可以再次去试试其他的,比如将硬件hwclock里面的时间设置了,
用hwclock -s把rtc时间写到Linux系统时间里面去。
【小提示】
为了使系统时间和RTC时间同步,而不用等待Linux系统启动后,要麻烦地,每次都这样输入命令去同步Linux系统时间和硬件RTC的时间,
可以在初始化文件中添加命令hwclock –s,使每次开机时读取硬件RTC时间,并同步给Linux系统时间。
具体方法是:
在etc/init.d/rcS(旧版本的,应该是/etc/inittab)中添加
 

/bin/hwclock -s


即可。
【资料引用】
1.关于linux的RTC驱动
http://blog.csdn.net/myleeming/archive/2008/11/05/3228154.aspx

2.RTC\date
http://hi.baidu.com/grdd/blog/item/554c2b3f11d612e455e7234a.html

3.

4.




阅读(1424) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~