如何在linux内核模块中添加定期计时器回调

时间:2013-11-30 13:45:49

标签: linux linux-kernel embedded interrupt

我正在开发一个Linux内核模块,该模块为来自定制板的中断注册回调,并将接收到的数据放在char设备接口后面的队列中,由应用程序处理。即使没有来自电路板的中断,该模块也需要不断监视和测量来自电路板的中断和数据,因此它有另一个根据时间触发的回调。

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

问题是我们必须失去一些Linux以这种方式管理时间的能力,因为只有一个rtc-cmos或板模块可以同时加载(显然我们选择了板卡模块) )。

Linux内核来自Debian 7.2 stable附带的linux-source包,版本为3.2+46。目标架构是i386 PC。

我不是内核开发人员,因此对内核模块开发没有全面了解,但我正在努力寻找自己的方式,这些是解决方案中最接近我的想法:

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

我想可能有一种简单而标准的方法可以做到这一点,如果有人会对这些解决方案中的任何一个做出评论或建议其他解决方案,我会很高兴。

1 个答案:

答案 0 :(得分:4)

  

可能有一个标准的内核API

当然有。在内核模块中需要一个计时器可能并不罕见。

我对API知之甚少,但我知道它存在。如果您要正确编写内核模块,您应该得到一本书或其他东西;有几种。 1 无论如何,一种传统的方法是:

#include <linux/timer.h>

schedule_timeout(jiffies);
那是一种被动的睡眠。 Jiffies是一个基于处理器内250 HZ刻度的单位,尽管这可能是可配置的。该标头有各种其他功能,这里的a brief discussion涉及2.6内核,但我认为3.x必须仍然与此兼容,因为包括驱动程序在内的很多源都比这个要早。有一种简单的方法可以找到当然。

如果你想延迟一秒,Jiffies可能会好的。由于调度程序延迟,在毫秒级别上被动睡眠的粒度是常规内核的问题,但在ktime.h中也存在纳秒粒度API(该链接再次来自2.6内核,但文件仍然过时2005年在3.11来源,所以没有改变)。请记住,linux还具有纳秒粒度的用户空间计时器,但这并不意味着它们实际上会因为调度程序延迟而在该级别上计时(并且可能对内核空间中的被动计时器也是如此)。

您可以访问RTC而不是使用处理器/内核滴答,但有一些缺点:

  • 并非所有系统都有一个。
  • 意味着忙着循环。

并没有真正的优势。 AFAIK RTC 不被认为比处理器滴答更准确。

1 您应该明智地使用的另一个资源是Linux Kernel Mailing List(LKML),这是开发人员所在的地方,他们确实回答了问题。请注意,列表中每天有数百封邮件。