HI
我们正在开发一款采用 i.MX8ULP 处理器的产品,我们的一位用户注意到时间漂移非常糟糕(这取决于单位,有些单元 " 在大约一小时内只有 " 快几秒钟,但有些设备很容易以每分钟一秒的速度加快)
我已经在我们的 i.mx8ULP EVK 上进行了复制,运行最新的电路板支持包(LF_v6.12.20-2.0.0),使用 chrony 来测量偏差(需要互联网)
imx8ulpevk login: root
# stop ntpd/timesyncd to avoid interfering... (why are both running?!)
root@imx8ulpevk:~# systemctl disable --now ntpd
root@imx8ulpevk:~# systemctl disable --now systemd-timesyncd
# run chronyd as a container for simplicity.
# tmpfs ensures drift state is not preserved accross restarts
root@imx8ulpevk:~# docker run --net=host --name ntp -d simonrupf/chronyd
Unable to find image 'simonrupf/chronyd:latest' locally
latest: Pulling from simonrupf/chronyd
d69d4d41cfe2: Pull complete
5f93ef52bdbb: Pull complete
3a84ecea1ef1: Pull complete
Digest: sha256:6c2a693438b6c663f151516ccce21b409f0891df673a34cadf133c74b35b7b6b
Status: Downloaded newer image for simonrupf/chronyd:latest
15a0cdd35648868fe8592e98f7d653a6e9fd5abec5ff8c335b6edffc69617fe8
# (here need to wait a bit for the Frequency error to be computed
# based on measurements stability. If it doesn't compute it helps
# to run something like `chronyc burst 4/10`)
root@imx8ulpevk:~# docker exec ntp chronyc tracking
Reference ID : 2D4D1467 (v4.ntp.admtan.jp)
Stratum : 3
Ref time (UTC) : Tue Jul 22 07:26:57 2025
System time : 0.343799949 seconds fast of NTP time
Last offset : +0.068965137 seconds
RMS offset : 0.129153565 seconds
Frequency : 12426.411 ppm fast
Residual freq : +0.000 ppm
Skew : 100.904 ppm
Root delay : 0.018474324 seconds
Root dispersion : 0.001048955 seconds
Update interval : 2.0 seconds
Leap status : Normal因此,这里有趣的一行是 "频率"(Frequency),描述为"。"频率 "是指如果没有 chronyd 的校正,系统时钟出错的速度。单位是 ppm(百万分之一)。例如,1 ppm 的值意味着,当系统时钟认为它前进了 1 秒时,它实际上相对于真实时间前进了 1.000001 秒。"
在这种情况下,这意味着 12426.411 * 10^-6 * 3600 = ~45 秒将在 1 小时内过得太快,但重启后似乎会发生变化
那么,有几个问题:
- arch_sys_counter 的时钟从何而来?这是电路板上的一颗晶体精度低的问题吗?(... 如果是这样,我们就从 EVK 复制了这个缺陷......)
-我注意到有两个时钟源可用,切换到 imx-tpm 要稳定得多(要么是 `echo imx-tpm > /sys/devices/system/clocksource/clocksource/clocksource0/current_clocksource0/current_clocksource `或者在启动参数中设置 `clocksource=imx-tpm`),有什么理由不是默认值吗?我正在考虑发送一个补丁,将 32 位计数器的默认值从 200 提高到 500(需要高于 400 才能优先于拱形系统计数器),但如果有任何理由的话,我想了解为什么要先选择一个较低的值。
谢谢
谢谢您的答复!
> 它由一个内部 1 MHz LPO 驱动,其频率稳定性本身就受到限制,因此 arch_sys_counter 出现了精度问题。
啊!这有感知,谢谢
> 这是关于启用双 TPM 定时器的补丁。要进行测试,您需要重建 ATF 以生成新的 bl31.bin。
我这周休假,下周再检查(尤其是 IMX8ULP_TPM_TIMERS 的 atf 代码是在 lf-6.12.20-2.0.0 中添加的,而我们使用的是较早的分支,因此我需要先重新构建并验证)。
我们一直使用单个 tpm 实例运行,只选择了 imx-tpm 时钟源,我没有注意到这个问题:
> 启用基于 TPM 的计时需要在两个 CPU 内核上实例化 TPM 定时器,以保留每个内核的事件处理功能
您能解释一下只启用一个 tpm 定时器有什么问题吗?"只是" 增加 cpu0 的负载,使系统时钟与时俱进?还是有其他弊端?
再次感谢您、
多米尼克
你好
内部团队也进行了同样的测试,证实arch_sys_counter 的精度相对较差,而 imx-tpm 定时器的精度明显更高。如前所述,ARM 通用计时器包括一个系统计数器和一组每核计时器。
arch_sys_counter 上观察到精度问题。如果您的应用需要更严格的定时精度,则可以改用TPM作为时钟源。启用基于 TPM 的计时需要在两个 CPU 内核上实例化 TPM 定时器,以保留每个内核的事件处理功能。
这是关于启用双 TPM 定时器的补丁。要进行测试,您需要重建 ATF 以生成新的 bl31.bin。
make -j8 PLAT=imx8ulp CROSS_COMPILE=aarch64-poky-linux- bl31 IMX8ULP_TPM_TIMERS=1
而且你需要使用 imx8ulp-evk-tpm.dtb 设备树文件。
有任何问题,请告诉我。
顺祝商祺!
你好
既然您能在 EVK 中重现该问题,让我与内部团队核实一下。
我将检查是否可以通过软件解决这个问题。
顺祝商祺!
你好
我们通常建议公差为 +/-50ppm 或更小,因此,这样就可以了。
顺祝商祺!
你好
你是说这有助于解决时间问题?还是仍然存在?
顺祝商祺!
你好
感谢您在 EVK 中对此进行测试,这个问题以前从未被报告过。
关于您的问题
通用计时器为 Arm 内核提供了标准化的计时器框架。通用定时器包括一个 系统计数器和几组每个内核的定时器。
系统计数器是一种常开设备,它提供固定频率递增的系统计数。系统计数值会广播给系统中的所有内核,让内核共同了解时间的流逝。由 SCTR 实施。
系统计数器输入两个计数器时钟源,并将灰色编码的计数器值和中断信号(每个比较帧一个)输出到平台的中断控制器。
RESET后,系统计数器被禁用,计数值重置为零并选择基本频率。
一旦启用计数器,它将在所选时钟的每个上升沿增加相应的值。
Screenshot 2025-07-22 143804.png
顺祝商祺!