<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>芷菁博客 &#187; rtc</title>
	<atom:link href="http://www.stars625.com/tag/rtc/feed" rel="self" type="application/rss+xml" />
	<link>http://www.stars625.com</link>
	<description>记录生活点滴，分享学习体会，专注微嵌开发。</description>
	<lastBuildDate>Sun, 18 Jul 2010 02:55:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>解决嵌入式系统中实时时钟RTC无法工作问题</title>
		<link>http://www.stars625.com/embedrtc.html</link>
		<comments>http://www.stars625.com/embedrtc.html#comments</comments>
		<pubDate>Fri, 17 Jul 2009 09:40:29 +0000</pubDate>
		<dc:creator>stars_625</dc:creator>
				<category><![CDATA[嵌入开发]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[rtc]]></category>
		<category><![CDATA[sysfs]]></category>

		<guid isPermaLink="false">http://www.stars625.com/?p=146</guid>
		<description><![CDATA[最近在做NTPD网络时间同步的时候，发现开发板自身的硬件时钟不起作用，每次重启后系统时间都回到1970年；并且使用hwclock命令既不能查看硬件时钟，也不能把系统时间同步到硬件时钟里去，在多次试验后发现是由于驱动和设备文件的原因导致的。]]></description>
			<content:encoded><![CDATA[<p>在嵌入式Linux下完成了NTPD的移植后，发现硬件时钟无法使用，具体现象为：每次重启后系统时间回到1970年；使用hwclock命令无法操作硬件时钟，提示无法识别的时间格式；“cat /proc/drivers/rtc”显示乱码。按照由易到难、由软到硬的解题思路，先从软件上下手。</p>
<p>因为开发板中目前使用的是Busybox自带的一个hwclock工具，可能精简过了，重新下载源码包编译了一个完整的hwclock，传到开发板运行，现象照旧，只是提示信息变了变。查看“/dev”目录下的确有rtc这个设备，用“ls -l”查看其设备号也都正常。</p>
<p>查看rtc的手册，没耐心看下去直接跳到最后，看到在“/usr/src/linux/Documentation”目录下有个“rtc.txt”文件（目录可能略有不同），里面有一段RTC的测试程序，拷出来编译后放到开发板上进行测试，还是有问题，再把测试程序中的其它部分都去除，只保留读写时间的测试项目，运行后发现读到的还是1970年的时间，不可写入。从测试代码中可以看到，在操作RTC的时候跟操作普通文件一样，首先打开设备文件“/dev/rtc”，再通过“ioctl”命令传入不同的参数（RTC_RD_TIME、RTC_UIE_ON、RTC_ALM_SET）进行操作。</p>
<p>至此，经过多次软件方面的测试，可以确定不是程序问题，那么就有可能是设备驱动或硬件问题。</p>
<p>由于重新编译过内核，不太确定编译选项，遂把开发板原始内核文件写进去，现象依旧。没办法看看开发板的硬件配置吧，看了开发板的手册，发现RTC不是使用MCU自带的时钟，而是使用了一个外扩的串行时钟芯片DS1339，它与MCU通过IIC总线进行通讯，到开发板上果然找到了该芯片，非常小，并且旁边还有一个时钟晶振，第一反应会不会是内核中没有把该驱动编进去呢。</p>
<p>打开内核配置选项，在RTC目录下找到了使用DS1339的配置选项，编进内核重新启动，在Log中出现了“rtc-ds1307 0-0068: rtc core: registered ds1339 as rtc0”，非常兴奋，总算有起色了，但是通往成功的道路往往并不是一帆风顺的。</p>
<p>重复了开头软件测试的过程，一如继往地无效，只有在“cat /proc/drivers/rtc”的时候有点反应，可以正常显示时间了，而且来到了新世纪2000年了，重启了几次，发现此处的时间是可以正常往前走的，感觉这边的时间显示的应该就是硬件时钟里的时间了，可为什么通过hwclock还是无法访问呢。</p>
<p>跑到“/dev”目录下找不到“rtc0”设备文件，明显与Log中关于“registered ds1339 as rtc0”冲突，手工建一个设备“rtc0”吧，主次设备号又不知道，乱建了几个都无效，而且还搞重启了。</p>
<p>后来才发现“/dev/rtc”对应内核中的GenRTC－－General RTC通用的RTC，就是为了应付某些命令产生的一个假的设备文件，并不能产生实际作用，读出来的时间也永远是1970年；可是我们的“rtc0”去哪了呢，跟踪了源码无解，不过有个意外发现：在注册RTC时会同时在三个地方创建文件，一个是“/proc/drivers/rtc”就是前面一直用的，用来反映设备状态的文件，该文件目前正常；一个是“/dev/rtc0”目前没有；最后一个是“/sys/class/rtc/rtc0”也没找到，“/sys”下整个就是空的。当然这三处与内核选项中也是有对应关系的，如果你在内核中没打开这三个相关选项，对应的文件也是不会创建的。</p>
<p>关于“/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”目录已经能看到丰富的设备文件信息了，赶紧把这句话也加到启动脚本中吧。</p>
<p>“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”。世界总于回复了平静，一切都按秩序正常的工作了，成就感又一次占领了至高点。</p>
<p>前面提到通过“/dev”管理设备有着固有的缺点，其中之一就是不能智能的创建设备文件，也可能出现设备文件与设备不对应的情况，在嵌入式开发中由于缺少其它服务脚本更有可能产生。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stars625.com/embedrtc.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
