我正在开发一个Linux内核模块,该模块为来自定制板的中断注册回调,并将接收到的数据放在char设备接口后面的队列中,由应用程序处理。即使没有来自电路板的中断,该模块也需要不断监视和测量来自电路板的中断和数据,因此它有另一个根据时间触发的回调。
当前实现使用RTC中断作为常量定时器源。我禁用内核RTC驱动程序(CONFIG_RTC_DRV_CMOS
)并请求IRQ 8并将计时器回调挂钩为RTC中断处理程序。每秒从RTC芯片产生中断。
问题是我们必须失去一些Linux以这种方式管理时间的能力,因为只能加载一个rtc-cmos
或板模块(显然我们选择了板模块)
目标架构是i386 PC。
我不是内核开发人员,因此对内核模块开发没有全面了解,但我正在努力寻找自己的方式,这些是解决方案中最接近我的想法:
request_irq(8, rtc_handler, IRQF_SHARED, rtc_handler)
?)或链式IRQ处理程序。我想可能有一种简单而标准的方法可以做到这一点,我很高兴如果有人会对这些解决方案中的任何一个做出评论或建议其他解决方案。
答案 0 :(得分:10)
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;
}
答案 1 :(得分:1)
您可能想要使用tasklet,请参阅linux/interrupt.h
。