在嵌入式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的使用。
答案 0 :(得分:1)
HR计时器和printk
使用不同的时间源,因此用它们衡量的间隔不需要相等。
printk
使用低分辨率(但很快)的时间源,基于 jiffies 。您可以通过名称猜测HR计时器使用具有更高分辨率的时间源(如果可用)。
您可以通过修复步骤检查计时器的字段._softexpires
和.node.expires
是否增加。正是这些字段负责触发计时器。