I am working on a Linux kernel module that registers a callback for interrupts that come from a custom-made board and puts the received data in a queue behind a char device interface to be processed by an application. This module needs to constantly monitor and measure the interrupts and data that comes from the board even if no interrupt comes from the board, so it has another callback that triggers according to time.
Current implementation uses RTC interrupt as a constant timer source. I disable kernel RTC drivers (CONFIG_RTC_DRV_CMOS
) and request for IRQ 8 and hook the timer callback as RTC interrupt handler. Interrupts are generated every second from RTC chip.
The problem is we have to lose some of Linux's ability to manage time in this way, because only one of rtc-cmos
or the board module can be loaded at once (and obviously we've chosen the board module).
Target architecture is i386 PC.
I'm not a kernel developer and so don't have a big picture on kernel module development, but I'm trying to find my way and these are nearest thing to solution that come to my mind:
request_irq(8, rtc_handler, IRQF_SHARED, rtc_handler)
?) or chainload IRQ handlers.I suppose there might be a simple and standard way to do this and I would be glad If anyone would comment on either of these solutions or suggest others.
Actually, the Linux kernel provides two types of timers called dynamic timers and interval timers. First type of timers is used by the kernel, and the second can be used by user mode. The timer_list structure contains actual dynamic timers.
The global variable “jiffies” holds the number of ticks that have occurred since the system booted. On boot, the kernel initializes the variable to zero, and it is incremented by one during each timer interrupt. Thus, because there are HZ timer interrupts in a second, there are HZ jiffies in a second.
Each occurrence of a timer interrupt triggers the following major activities: Updates the time elapsed since system startup. Updates the time and date. Determines how long the current process has been running on the CPU and preempts it if it has exceeded the time allocated to it.
This patch introduces a new subsystem for high-resolution kernel timers. One might ask the question: we already have a timer subsystem (kernel/timers.
Linux kernel high-resolution timer hrtimer
is an option.
http://lwn.net/Articles/167897/
Here what I do:
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With