解决嵌入式系统中实时时钟RTC无法工作问题

Posted: 七月 17th, 2009 | Views: 1,031 次浏览 | 4 Comments »

最近在做NTPD网络时间同步的时候,发现开发板自身的硬件时钟不起作用,每次重启后系统时间都回到1970年;并且使用hwclock命令既不能查看硬件时钟,也不能把系统时间同步到硬件时钟里去,在多次试验后发现是由于驱动和设备文件的原因导致的。

在嵌入式Linux下完成了NTPD的移植后,发现硬件时钟无法使用,具体现象为:每次重启后系统时间回到1970年;使用hwclock命令无法操作硬件时钟,提示无法识别的时间格式;“cat /proc/drivers/rtc”显示乱码。按照由易到难、由软到硬的解题思路,先从软件上下手。

因为开发板中目前使用的是Busybox自带的一个hwclock工具,可能精简过了,重新下载源码包编译了一个完整的hwclock,传到开发板运行,现象照旧,只是提示信息变了变。查看“/dev”目录下的确有rtc这个设备,用“ls -l”查看其设备号也都正常。

查看rtc的手册,没耐心看下去直接跳到最后,看到在“/usr/src/linux/Documentation”目录下有个“rtc.txt”文件(目录可能略有不同),里面有一段RTC的测试程序,拷出来编译后放到开发板上进行测试,还是有问题,再把测试程序中的其它部分都去除,只保留读写时间的测试项目,运行后发现读到的还是1970年的时间,不可写入。从测试代码中可以看到,在操作RTC的时候跟操作普通文件一样,首先打开设备文件“/dev/rtc”,再通过“ioctl”命令传入不同的参数(RTC_RD_TIME、RTC_UIE_ON、RTC_ALM_SET)进行操作。

至此,经过多次软件方面的测试,可以确定不是程序问题,那么就有可能是设备驱动或硬件问题。

由于重新编译过内核,不太确定编译选项,遂把开发板原始内核文件写进去,现象依旧。没办法看看开发板的硬件配置吧,看了开发板的手册,发现RTC不是使用MCU自带的时钟,而是使用了一个外扩的串行时钟芯片DS1339,它与MCU通过IIC总线进行通讯,到开发板上果然找到了该芯片,非常小,并且旁边还有一个时钟晶振,第一反应会不会是内核中没有把该驱动编进去呢。

打开内核配置选项,在RTC目录下找到了使用DS1339的配置选项,编进内核重新启动,在Log中出现了“rtc-ds1307 0-0068: rtc core: registered ds1339 as rtc0”,非常兴奋,总算有起色了,但是通往成功的道路往往并不是一帆风顺的。

重复了开头软件测试的过程,一如继往地无效,只有在“cat /proc/drivers/rtc”的时候有点反应,可以正常显示时间了,而且来到了新世纪2000年了,重启了几次,发现此处的时间是可以正常往前走的,感觉这边的时间显示的应该就是硬件时钟里的时间了,可为什么通过hwclock还是无法访问呢。

跑到“/dev”目录下找不到“rtc0”设备文件,明显与Log中关于“registered ds1339 as rtc0”冲突,手工建一个设备“rtc0”吧,主次设备号又不知道,乱建了几个都无效,而且还搞重启了。

后来才发现“/dev/rtc”对应内核中的GenRTC--General RTC通用的RTC,就是为了应付某些命令产生的一个假的设备文件,并不能产生实际作用,读出来的时间也永远是1970年;可是我们的“rtc0”去哪了呢,跟踪了源码无解,不过有个意外发现:在注册RTC时会同时在三个地方创建文件,一个是“/proc/drivers/rtc”就是前面一直用的,用来反映设备状态的文件,该文件目前正常;一个是“/dev/rtc0”目前没有;最后一个是“/sys/class/rtc/rtc0”也没找到,“/sys”下整个就是空的。当然这三处与内核选项中也是有对应关系的,如果你在内核中没打开这三个相关选项,对应的文件也是不会创建的。

关于“/dev”与“/sys”是有一些历史原因的,前者是Linux 2.4内核使用的设备管理方式,由于固有的缺点到了Linux 2.6就不再使用了,改用“sysfs”虚拟文件系统来进行管理设备,但为什么我们的“/sys”目录下是空的呢,查看了“/etc/fstab”、“/etc/rc.d/init.d/filesystem”,原来在后者的初始化过程中只挂载了“/proc”,遂依照挂载了“sysfs”文件系统:“mount -n -t sysfs sysfs /sys”,此时在“/sys”目录已经能看到丰富的设备文件信息了,赶紧把这句话也加到启动脚本中吧。

“cat /sys/class/rtc/rtc0/dev”显示“254:0”这应该就是传说中的主、次设备号了吧,系统没有自动帮我们创建“/dev/rtc0”那自己手工建一个吧“mknod /dev/rtc0 c 254 0”,这回使用测试程序能读出时间了,用hwclock还是无效,完全正常,因为hwclock默认操作的是“/dev/rtc”,我们可以通过给hwclock命令增加参数指定设备文件,也可以把原来的“/dev/rtc”删除,建一个指向“/dev/rtc0”的链接“ln -s /dev/rtc0 /dev/rtc”。世界总于回复了平静,一切都按秩序正常的工作了,成就感又一次占领了至高点。

前面提到通过“/dev”管理设备有着固有的缺点,其中之一就是不能智能的创建设备文件,也可能出现设备文件与设备不对应的情况,在嵌入式开发中由于缺少其它服务脚本更有可能产生。

原创文章,转载请注明:转载自 芷菁博客 [ http://www.stars625.com/ ]
本文链接地址:http://www.stars625.com/embedrtc.html

Filed under: 嵌入开发 | Tags: , ,

4 Comments on “解决嵌入式系统中实时时钟RTC无法工作问题”

  1. V 说:

    路过。。。

  2. 匿名 说:

    斑竹,我想问你下DS1339的问题,在linux下的驱动问题,麻烦你看见留言后,加我QQ84695046,谢谢,急、、、

    • stars_625 说:

      你没留邮件,所以无法回复到邮件了,QQ很少上,所以联系不方便,在网页底下有邮箱,麻烦用邮箱联系吧!

  3. 匿名 说:

    O(∩_∩)O


Leave a Reply

  • Name
  • Mail (will not be published)
  • Website