i.mx8 RTC问题

发布于:2025-07-17 ⋅ 阅读:(17) ⋅ 点赞:(0)

项目场景:

需要增加外置RTC,保证时间的精准。


问题描述:

基本情况,外置i2c接口的RTC,注册、读写都正常,但是偶发性重启后,系统时间是2022,rtc时间是1970,都像是恢复了默认时间一样。


原因分析:

几个名词含义:

  • 系统时钟(date):存储在内存中,由操作系统维护,断电后会丢失,依赖硬件时钟初始化。
  • 硬件时钟(hwclock):由主板电池供电的独立时钟,断电后仍能运行,用于系统启动时初始化系统时钟。
  • UTC时间:全球统一时间。
  • CST时间:我国采用时间,东八区时间,UTC+8。
  • 例如:硬件时钟显示10:00 UTC,系统时钟若为北京时间(UTC+8),则显示18:00

设置时间脚本:

#/bin/bash
echo close ntp
timedatectl set-ntp false
echo time set rtc1
date -s "2025-07-16 8:00:00" && hwclock -w -f /dev/rtc1
echo print rtc1
hwclock -f /dev/rtc1
echo system to rtc1
hwclock --systohc -u 
echo show rtc1
hwclock -u 
echo sync to sys
hwclock --hctosys -u

这样设置后,date返回的系统时间,以及hwclock返回的rtc时间都是正确的,但是奇怪的事情发生了,若干次重启后,date显示2022,hwclock显示1970。

于是查看内核打印信息,是怎么说的:

内核显示上电时,就是把rtc读给了系统啊,但是确实是读了1970,那原因在于,nxp有自己集成的一个rtc0是默认的,实际上通过hwclock查的是rtc0,并不是我的外置rtc,通过指令可以看到,外置的rtc1实际上是一直正常工作的。


解决方案:

那解决的问题就是变成了:干掉rtc0,使能rtc1,有很多的解决办法,我的解决办法是简单粗暴,改设备树。

其中在NXP的设备树中,我找到了他对自己rtc的定义

			snvs: snvs@30370000 {
				compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd";
				reg = <0x30370000 0x10000>;

				snvs_rtc: snvs-rtc-lp {
					compatible = "fsl,sec-v4.0-mon-rtc-lp";
					regmap =<&snvs>;
					offset = <0x34>;
					interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
						     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
					clocks = <&clk IMX8MP_CLK_SNVS_ROOT>;
					clock-names = "snvs-rtc";
				};

				snvs_pwrkey: snvs-powerkey {
					compatible = "fsl,sec-v4.0-pwrkey";
					regmap = <&snvs>;
					interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
					clocks = <&clk IMX8MP_CLK_SNVS_ROOT>;
					clock-names = "snvs-pwrkey";
					linux,keycode = <KEY_POWER>;
					wakeup-source;
					status = "disabled";
				};
			};

snvs_rtc就是我们的目标rtc,把它干掉就可以了。

在自己的设备树xxx.dts里加上这一句,因为我是引用了NXP的imx8mp.dtsi的。

&snvs_rtc{
	status = "disabled";
};

至此,大功告成,时间正常,内核打印只显示这个i2crtc了,只是映射从从rtc1变为了rtc0。


最后:记得更改本地时区。

timedatectl set-timezone Asia/Shanghai


网站公告

今日签到

点亮在社区的每一天
去签到