【问题标题】:How to add a periodic timer callback in a linux kernel module [duplicate]如何在linux内核模块中添加定期定时器回调[重复]
【发布时间】:2013-12-16 22:43:51
【问题描述】:

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

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

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

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,我不知道。

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

【问题讨论】:

    标签: linux linux-kernel embedded interrupt


    【解决方案1】:

    也许有一个标准的内核 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),这是开发人员所在的位置,他们确实会回答问题。请注意,该列表每天有数百条消息。

    【讨论】:

    • 感谢您的出色回答,我将使用内核计时器重写和测试模块并通知您结果。
    猜你喜欢
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多