如何在Linux内核模块中添加peridic定时器callback

我正在开发一个Linux内核模块,该模块注册来自定制电路板的中断的callback函数,并将接收到的数据置于字符设备接口后面的队列中,以供应用程序处理。 即使主板没有中断,该模块也需要不断监控和测量来自主板的中断和数据,所以还有另外一个按时间触发的callback。

当前实现使用RTC中断作为常量定时器源。 我禁用内核RTC驱动程序( CONFIG_RTC_DRV_CMOS )并请求IRQ 8并挂接定时器callback作为RTC中断处理程序。 RTC芯片每秒产生一次中断。

问题是我们不得不失去一些Linuxpipe理时间的能力,因为只有一个rtc-cmos或板子模块可以一次加载(显然我们select了板子模块)。

目标架构是i386个人电脑。

我不是一个内核开发人员,所以对内核模块开发没有太多的了解,但是我试图find自己的方式,而这些对我来说是最接近解决scheme的东西:

  • 以某种方式共享两个模块之间的IRQ 8(可能像request_irq(8, rtc_handler, IRQF_SHARED, rtc_handler) ?)或chainload IRQ处理程序。
  • 寻找另一种方法将处理程序从内核模块挂接到RTC中断,而不是注册IRQ 8。
  • 寻找另一个可以在内核模块中使用的1秒定时器事件源,也许有一个标准的内核API,我不知道。

我想可能有一个简单而标准的方法来做到这一点,我会很高兴,如果有人会对这些解决scheme发表评论或build议其他人。

Linux内核高分辨率定时器hrtimer是一个选项。 http://lwn.net/Articles/167897/

这里我做什么:

 #include <linux/interrupt.h> #include <linux/hrtimer.h> #include <linux/sched.h> static struct hrtimer htimer; static ktime_t kt_periode; static void timer_init(void) { kt_periode = ktime_set(0, 104167); //seconds,nanoseconds hrtimer_init (& htimer, CLOCK_REALTIME, HRTIMER_MODE_REL); htimer.function = timer_function; hrtimer_start(& htimer, kt_periode, HRTIMER_MODE_REL); } static void timer_cleanup(void) { hrtimer_cancel(& htimer); } static enum hrtimer_restart timer_function(struct hrtimer * timer) { // @Do your work here. hrtimer_forward_now(timer, kt_periode); return HRTIMER_RESTART; } 

您可能想要使用一个tasklet,请参阅linux/interrupt.h