Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/kthread.h>
#include <linux/delay.h>
MODULE_LICENSE("Dual BSD/GPL");
#define RX_POLL_PERIOD_MIN_US 800
#define RX_POLL_PERIOD_MAX_US 3000
#define PAUSE_MS 10
static struct hrtimer hr_timer;
static struct task_struct *t1;
static unsigned long long counter=0;
static void my_timer_forward(struct hrtimer *timer) {
hrtimer_set_expires_range(timer,
ktime_add(timer->base->get_time(),
ktime_set(0, RX_POLL_PERIOD_MIN_US *
NSEC_PER_USEC)),
ktime_set(0, (RX_POLL_PERIOD_MAX_US -
RX_POLL_PERIOD_MIN_US) *
NSEC_PER_USEC));
}
enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer ) {
udelay(50);
printk(KERN_ALERT "!");
my_timer_forward(timer);
counter++;
return HRTIMER_RESTART;
}
static int thread_func(void* data) {
unsigned long long n;
while (!kthread_should_stop()) {
printk(KERN_ALERT ">");
hrtimer_cancel(&hr_timer);
printk(KERN_ALERT "?");
n=counter;
msleep(PAUSE_MS);
BUG_ON(n != counter);
my_timer_forward(&hr_timer);
printk(KERN_ALERT "<");
hrtimer_start_expires(&hr_timer, HRTIMER_MODE_ABS);
msleep(PAUSE_MS);
}
return 0;
}
static int hello_init(void) {
printk(KERN_ALERT "Hello, world\n");
hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
hr_timer.function = my_hrtimer_callback;
my_timer_forward(&hr_timer);
hrtimer_start_expires(&hr_timer, HRTIMER_MODE_ABS);
t1 = kthread_run(thread_func, NULL, "my_thread");
return 0;
}
static void hello_exit(void) {
kthread_stop(t1);
hrtimer_cancel(&hr_timer);
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.