How to Implement Periodic Timer in Linux Kernel

Linux Kernel already has a timer module that allows us to create timers which are not periodic by default. We can specify a callback function and a timeout value to the module. After expiry of the timeout value, the callback function will be called. Problem is the callback function will be called only once. Here we’ll see how to make the timer periodic. That means the callback function will continued to be called in the interval specified by the timeout value. The strategy is very simple. When our callback function will be called, we’ll first restart the timer, then will do the work whatever we want to do in every timeout. Here is the code of our periodic timer.

Read also: Implement periodic timer in Linux user space.

#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/timer.h>

int g_time_interval = 10000;
struct timer_list g_timer;

void _TimerHandler(unsigned long data)
{
    /*Restarting the timer...*/
    mod_timer( &g_timer, jiffies + msecs_to_jiffies(g_time_interval));

    printk(KERN_INFO "Timer Handler called.\n");
}

static int __init my_init(void)
{
    printk(KERN_INFO "My module inserted into kernel!!!.\n");

    /*Starting the timer.*/
    setup_timer(&g_timer, _TimerHandler, 0);
    mod_timer( &g_timer, jiffies + msecs_to_jiffies(g_time_interval));

    return 0;
}

static void __exit my_exit(void)
{
    del_timer(&g_timer);
    printk(KERN_INFO "My module exited from kernel!!!\n");
}

module_init(my_init);
module_exit(my_exit);

In this example, we have two global variables, g_time_interval and g_timer. We assigned the timeout value, 10000 ms (10 second) to the g_time_interval and g_timer will be used to store the timer. In the module init function my_init(), we started the timer in line 22 and 23. We passed the _TimerHandler() function to the setup_timer() function as callback function. That means, the _TimerHandler() function will be called after 10 seconds.  In the _TimerHandler() function we have a print that “Timer Handler called” but before that we restarted the timer in line 12. This is very important to make the timer periodic.

Read also:

Create a simple Makefile to compile the above program. The Makefile will loop like:

obj-m += test.o

all:
       make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

If you make the program using this Makefile, the kernel module test.ko will be created in the same directory. You can now install the module in the kernel.

insmod test.ko

If you look in the “/var/log/messages” file, you will see the “Timer Handler called” print periodically.

tail -f /var/log/messages

[10726.552027] My module inserted into kernel!!!
[10736.599645] Timer Handler called.
[10746.654342] Timer Handler called.
[10756.701993] Timer Handler called.
[10766.757046] Timer Handler called.
[10776.807706] Timer Handler called.

We can also create a wrapper module that will provide a periodic timer functionality. User will simply create a timer and the user callback function will be called periodically without the need of restarting the timer in the callback function.

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

1
0
0
2
1
0