我正在开发一个Linux内核模块,该模块注册来自定制电路板的中断的callback函数,并将接收到的数据置于字符设备接口后面的队列中,以供应用程序处理。 即使主板没有中断,该模块也需要不断监控和测量来自主板的中断和数据,所以还有另外一个按时间触发的callback。
当前实现使用RTC中断作为常量定时器源。 我禁用内核RTC驱动程序( CONFIG_RTC_DRV_CMOS
)并请求IRQ 8并挂接定时器callback作为RTC中断处理程序。 RTC芯片每秒产生一次中断。
问题是我们不得不失去一些Linux以这种方式pipe理时间的能力,因为只有一个rtc-cmos
或者板子模块可以一次加载(显然我们select了板子模块)。
Linux内核来自Debian 7.2稳定版本的linux-source
软件包,版本为3.2+46
。 目标架构是i386个人电脑。
我不是一个内核开发人员,所以对内核模块开发没有太多的了解,但是我试图find自己的方式,而这些对我来说是最接近解决scheme的东西:
request_irq(8, rtc_handler, IRQF_SHARED, rtc_handler)
?)或chainload IRQ处理程序。 我想可能有一个简单和标准的方法来做到这一点,我会很高兴,如果有人会评论这些解决scheme或build议其他人。
也许有一个标准的内核API
当然有。 在内核模块中需要定时器可能并不少见。
我不太了解API,但我知道它存在。 如果你打算正确地编写一个内核模块,你应该得到一本书或其他东西; 有几个。 1无论如何,一个传统的方法是:
#include <linux/timer.h> schedule_timeout(jiffies);
那是一种被动的睡眠。 Jiffies是基于处理器内的250 HZ滴答的单元,虽然这可能是可配置的。 这个头文件还有其他各种功能,下面是关于 2.6内核的简要讨论 ,但是我认为3.x必须与这个兼容,因为包括驱动程序在内的很多源代码都比这个更早。 有一个简单的方法来找出当然。
如果你想延迟一秒,Jiffies可能没问题。 由于调度程序的延迟,毫秒级被动睡眠的粒度是一个常规内核的问题,但ktime.h中也有一个纳秒粒度API(该链接再次来自2.6内核,但该文件仍然是2005年的3.11来源,所以没有改变)。 请记住,linux也具有纳秒粒度的用户空间计时器,但这并不意味着它们实际上会因为调度程序延迟(在内核空间中被动定时器也是如此)而在该级别上进行计时。
您可以访问RTC而不是使用处理器/内核tick,但有一些缺点:
并没有真正的优势。 AFAIK RTC 不被认为比处理器滴答更准确。
1另一个你明智的使用的资源是Linux内核邮件列表 (LKML),这是开发者所在的位置,他们的确回答了问题。 被警告的名单有成百上千的消息每天的数量。