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

时间:2016-02-15 23:41:11

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

在嵌入式Linux内核模块中,我试图实现每秒发生的测量操作,我使用hrtimer来提供时序。以下功能是在设置定时器时注册的回调。值得关注的是为hrtimer的下一个回调触发器添加时间的正确方法。我正在使用' hrtimer_add_expires_ns'理解为这会将xx ns添加到上次为计时器设置的时间到#34;到期"。

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秒。我确实知道时间戳是存储消息的时间,但我希望时间会“消除”#34;而不是不断前进......如果计时器正在做我期望的那样,那就是在最后一个到期时间加一秒(而不是#34;现在")。

换句话说,我希望记录的时间戳总是试图从初始计时器开始时间的一秒的倍数(编辑时间戳以显示我期望的计时器在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的使用。

1 个答案:

答案 0 :(得分:1)

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

printk使用低分辨率(但很快)的时间源,基于 jiffies 。您可以通过名称猜测HR计时器使用具有更高分辨率的时间源(如果可用)。

您可以通过修复步骤检查计时器的字段._softexpires.node.expires是否增加。正是这些字段负责触发计时器。