In programming timer are used to perform a particular operation at regular interval, or later some time. Linux userspace programming support Alarms to support timing related operations. In this blog post we will discuss how to achieve timer or timing related operations in Kernel space.
Linux kernel provides software timer interface in kernel for device drivers and kernel modules to perform time based operations.
We are developing a simple timer example which can be run on Raspberry Pi to toggle GPIO 23 at every 500ms interval.
struct timer_list is one of the important structure defined in <linux/timer.h>
This structure has function pointer as member which will be called when timer expires.
Timer expiry is defined based on expires member of timer_list structure.
timer_setup: This kernel api take pointer to timer_list and expiry function which is to be executed on timer expiry ( here simple_timer_function).
mod_timer: This kernel api is used to define the expiry time for the timer structure. That is this used in timer expiry callback to reinitialize the timer with expiry time.
#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/timer.h> #include <linux/jiffies.h> #include <linux/gpio.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("c2plabs.com"); MODULE_DESCRIPTION("Module explains about Linux Kernel Timer"); MODULE_VERSION("1.21"); #define LED_PIN 23 void simple_timer_function(struct timer_list *); struct timer_list simple_timer; static int __init simple_timer_module_init (void) { timer_setup(&simple_timer,simple_timer_function,0); mod_timer(&simple_timer, jiffies + msecs_to_jiffies(500)); gpio_direction_output(LED_PIN,1); return 0; } void simple_timer_function(struct timer_list *timer) { static int count; printk(KERN_INFO" Timerfunction \n"); printk(KERN_INFO" HZ: %d \n",HZ); mod_timer (&simple_timer, jiffies + ( msecs_to_jiffies(500))); if (count) { gpio_direction_output(LED_PIN,1); count = 0; } else { gpio_direction_output(LED_PIN,0); count = 1; } } static void __exit simple_timer_module_exit (void) { del_timer(&simple_timer); } module_init(simple_timer_module_init); module_exit(simple_timer_module_exit);