当前位置: 首页 > 面试题库 >

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

商麒
2023-03-14
问题内容

我正在研究一个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 8 或链负载IRQ处理程序。
  • 寻找另一种方法将处理程序从内核模块挂接到RTC中断,而不是注册IRQ 8。
  • 寻找另一个可以在内核模块中使用的1秒计时器事件的来源,也许我没有标准的内核API。

我想可能会有一个简单而标准的方法来执行此操作,如果有人对这些解决方案中的任何一个发表评论或提出其他建议,我将感到非常高兴。


问题答案:

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;
}


 类似资料:
  • 主要内容:initramfe虚拟文件系统GRUB 加载了内核之后,内核首先会再进行二次系统的自检,而不一定使用 BIOS 检测的硬件信息。这时内核终于开始替代 BIOS 接管 Linux 的启动过程了。 内核完成再次系统自检之后,开始采用动态的方式加载每个硬件的模块,这个动态模块大家可以想象成硬件的驱动(默认 Linux 硬件的驱动是不需要手工安装的,如果是重要的功能,则会直接编译到内核当中;如果是非重要的功能,比如硬件驱动会编译为模块

  • 问题内容: 我有一个同时具有两个外部内核模块和一个用户空间守护程序的应用程序。我想在启动时从用C编写的守护程序代码中加载模块,然后在干净退出时将其卸载。我可以用比使用相应的方式更干净的方式加载它们吗? 问题答案: 最小的可运行示例 使用此简单的参数打印机模块,在QEMU + Buildroot VM和Ubuntu 16.04主机上进行了测试。 我们使用/ 和 Linux系统调用。 Linux内核为

  • MANAGING THE LINUX KERNEL AND LOADABLE KERNEL MODULES 所有操作系统至少由两个主要组件组成。其中第一个也是最重要的是内核。 内核位于操作系统的中心,控制着操作系统所做的一切,包括管理内存,控制 CPU,甚至控制用户在屏幕上看到的内容。操作系统的第二个元素通常被称为用户区域,几乎包括其他所有元素。 内核被设计成一个受保护或特权的区域,只能由 roo

  • 问题内容: 据我所知,要从内核空间通知用户空间,一种方法是使用轮询。这意味着内核驱动程序应首先提供轮询方法。下面的代码是从互联网上找到的,它确实有效! 我可以这样使它起作用: 然后 看结果。 但是如何添加轮询方法呢?我试了几次,但还是失败了。有人可以帮忙吗?谢谢! 问题答案: 您可以在内核本身中找到一些很好的示例。看下一个文件: 驱动程序/char/rtc.c fs / proc / kmsg.c

  • 我无法在gradle项目中添加自定义源代码集。如何初始化这里的版本号?我的gradle文件看起来像:

  • 问题内容: 我正在从事学术项目,该项目修改了一些代码并包含了新代码。 我正在使用QEMU加载修改后的内核并进行测试。 但是,我发现某些操作系统需要完整的操作系统才能进行调试。 没有它可能吗? 或者,这是可以与Kernel 2.6一起用于系统的发行版。除了运行程序的功能(包括网络支持)以外,发行版不需要具有任何功能。 问题答案: 我认为最简单的方法是使用buildroot http://buildr