linux - 为什么我在使用 linux hrtimer 进行一秒回调时会出现时间漂移?

标签 linux timer linux-kernel embedded-linux kernel-module

在嵌入式 linux 内核模块中,我正在尝试实现每秒发生的测量操作,并且我正在使用 hrtimer 来提供计时。下面的函数是设置定时器时注册的回调。值得关注的是为 hrtimer 的下一个回调触发器添加时间的正确方法。我使用“hrtimer_add_expires_ns”的理解是,这会将 xx ns 添加到上次设置的计时器“过期”时间。

static enum hrtimer_restart delay_callback (struct hrtimer* MeasDelay)
{
    hrtimer_add_expires_ns (MeasDelay, MS2NS(1000));

    printk (KERN_ALERT "Delay Callback (%d).\n", DelayCount);

    if (0 == DelayCount)
    {
        /* Reset delay counter */
        DelayCount = MEASDELAYSECS;

        /* Setup stuff to do when counter reaches zero */

    }
    else
    { 
        /* Drop the counter */
        DelayCount--;
    }

    return HRTIMER_RESTART;
}

当运行此代码并查看/var/log/syslog 时,我发现日志中存储的消息的“漂移”时间不断增加:

Feb 15 13:48:15 blah: [ 4731.033628] Delay Callback (5).  
Feb 15 13:48:16 blah: [ 4732.034576] Delay Callback (4).  
Feb 15 13:48:17 blah: [ 4733.035861] Delay Callback (3).  
Feb 15 13:48:18 blah: [ 4734.036855] Delay Callback (2).  
Feb 15 13:48:19 blah: [ 4735.038025] Delay Callback (1).  
Feb 15 13:48:20 blah: [ 4736.039170] Delay Callback (0).  
Feb 15 13:48:21 blah: [ 4737.040332] Delay Callback (5).  
Feb 15 13:48:22 blah: [ 4738.041493] Delay Callback (4).  
Feb 15 13:48:23 blah: [ 4739.042621] Delay Callback (3).  
Feb 15 13:48:24 blah: [ 4740.043792] Delay Callback (2).  
Feb 15 13:48:25 blah: [ 4741.044949] Delay Callback (1).  
Feb 15 13:48:26 blah: [ 4742.046109] Delay Callback (0).  
Feb 15 13:48:27 blah: [ 4743.047264] Delay Callback (5).  
Feb 15 13:48:28 blah: [ 4744.048436] Delay Callback (4).  
Feb 15 13:48:29 blah: [ 4745.049567] Delay Callback (3).  
Feb 15 13:48:30 blah: [ 4746.050725] Delay Callback (2).  
Feb 15 13:48:31 blah: [ 4747.051852] Delay Callback (1).  
Feb 15 13:48:32 blah: [ 4748.054040] Delay Callback (0).  

每个回调执行时间戳略多于预期的 1 秒。我确实知道时间戳是存储消息的时间,但我希望时间会“抖动”而不是不断前进......如果计时器正在做我期望的事情,即在最后一次过期后增加一秒时间(不是“现在”)。

换句话说,我希望记录的时间戳总是尝试从初始计时器开始时间起一秒的倍数(编辑时间戳以显示如果计时器在 xxxx.040000 开始时我的预期) :

Feb 15 13:48:21 blah: [ 4737.040073] Delay Callback (5).  
Feb 15 13:48:22 blah: [ 4738.040100] Delay Callback (4).  
Feb 15 13:48:23 blah: [ 4739.040098] Delay Callback (3).  
Feb 15 13:48:24 blah: [ 4740.040050] Delay Callback (2).  
Feb 15 13:48:25 blah: [ 4741.040110] Delay Callback (1).  
Feb 15 13:48:26 blah: [ 4742.040101] Delay Callback (0).  
Feb 15 13:48:27 blah: [ 4743.041234] Delay Callback (5).  
Feb 15 13:48:28 blah: [ 4744.040030] Delay Callback (4).  
Feb 15 13:48:29 blah: [ 4745.040075] Delay Callback (3).  
Feb 15 13:48:30 blah: [ 4746.040099] Delay Callback (2).  
Feb 15 13:48:31 blah: [ 4747.040057] Delay Callback (1).  
Feb 15 13:48:32 blah: [ 4748.040040] Delay Callback (0).  

感谢您帮助我们更好地理解 linux hrtimers 的使用。

最佳答案

HR 计时器和 printk 使用不同的时间源,因此它们测量的间隔不需要相等。

printk 使用基于 jiffies 的低分辨率(但快速)时间源。 HR 计时器,顾名思义,使用分辨率更高的时间源(如果可用)。

您可以检查计时器的字段 ._softexpires.node.expires 是否以 fixed 步长递增。正是这些字段负责触发计时器。

关于linux - 为什么我在使用 linux hrtimer 进行一秒回调时会出现时间漂移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35421143/

相关文章:

linux - 从 Shell 输入中检测元(特殊)键(Ctrl、Shift、Alt、Tab、Esc、Backspace)

c - 调用 fclose() 后,该文件多快可用于另一个线程?

c - 为什么 gcc 提示已经存在的库找不到?

Javascript 计时器返回 NaN

ios - 快速动画循环进度 View (计时器)

swift:计时器(每秒)+gestureRecognizer 使 GUI 崩溃

linux-kernel - Linux 内核可以作为 ARM TrustZone 安全操作系统运行吗?

Linux内核模块编程: makefile

c - 写入文件

c - 平台设备驱动的Major编号是怎么分配的?