我需要一个函数在我的驱动程序(内核模块)中每秒调用256个计时器。我正在使用RTC,它运行得很好。但由于需要有hwclock命令和中断共享问题,我不得不用另一种方式来获得一个计时器。 所以我试着用hrtimer。我的硬件配置几乎都很好。
但每当我在另一台具有不同硬件的机器上安装驱动程序时,hrtimer就不再有效了,即定时器功能每秒调用230次而不是每秒256次。两台机器都运行相同的Linux版本。实际上第二台机器运行在第一台机器上编译的Linux。并且还注意到第二个是奔腾Intel celeron 333MHz机器。
My linux is:
uname -a: Linux debian-32-pc 3.2.0-4-686-pae #1 SMP Debian 3.2.63-2+deb7u2 i686 GNU/Linux
代码是:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
void handle_timer();
size_t timestamp = 0;
static struct hrtimer hr_timer;
#define MS_TO_NS(x) (x * 1E6L)
#define HRTIMER_FREQUENCY 256
int HRTIMER_PERIOD = 1E9L / HRTIMER_FREQUENCY; // some time is actually wasted to rerun the timer
enum hrtimer_restart my_hrtimer_callback(struct hrtimer *timer){
handle_timer();
int overrun;
ktime_t now;
ktime_t period = (ktime_t){ .tv64 = HRTIMER_PERIOD }; // in nano seconds
for (;;) {
now = hrtimer_cb_get_time(timer);
overrun = hrtimer_forward(timer, now, period);
if (!overrun)
break;
}
return HRTIMER_RESTART;
}
void start_timer(){
ktime_t ktime;
ktime = ktime_set(0, HRTIMER_PERIOD);
hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hr_timer.function = &my_hrtimer_callback;
hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL);
}
void stop_timer(){
hrtimer_cancel(&hr_timer);
}
long cc = 0;
long ccc = 0;
void handle_timer(){
int i;
cc++;
if (cc==256){
cc=0;
ccc++;
printk("<1>Timer count %d %d (%d)\n", ccc, HRTIMER_PERIOD, HRTIMER_FREQUENCY);
}
}
static int __init _init(void)
{
printk(KERN_INFO "registered");
start_timer();
return 0;
}
static void __exit _exit(void)
{
stop_timer();
printk(KERN_INFO "unregistered");
}