#include #include #include #include #include #include #include #include #include //Timer Variable #define TIMEOUT 5000 //milliseconds static struct timer_list demo_timer; static unsigned int count = 0; dev_t dev = 0; static struct class *dev_class; static struct cdev demo_timer_cdev; static int __init demo_timer_driver_init(void); static void __exit demo_timer_driver_exit(void); /***************Driver fucntions******************/ static int demo_timer_open(struct inode *inode, struct file *file); static int demo_timer_release(struct inode *inode , struct file *file); static ssize_t demo_timer_read(struct file *filp, char __user *buf, size_t len, loff_t *off); static ssize_t demo_timer_write(struct file *filp, const char __user *buf, size_t len, loff_t *off); /*************************************************/ //File operation structure static struct file_operations fops = { .owner = THIS_MODULE, .read = demo_timer_read, .write = demo_timer_write, .open = demo_timer_open, .release = demo_timer_release }; //Timer Callback function. This will be called when timer expires void timer_callback(struct timer_list *timer){ /* do your timer stuff here */ pr_info("Timer Callback function Called [%d]\n", count++); /** * Re-enable timer. Because this function will be called only first time. * If we re-enable this will work like periodic timer. */ mod_timer(&demo_timer, jiffies + msecs_to_jiffies(TIMEOUT)); } /** * This function will be called when we open the device file */ static int demo_timer_open(struct inode *inode, struct file *file){ pr_info("Device File Opened...!!!\n"); return 0; } /** * This function will be called when we close the Device file */ static int demo_timer_release(struct inode *inode , struct file *file){ pr_info("Read Function\n"); return 0; } /** * This function will be called when we read the Device file */ static ssize_t demo_timer_read(struct file *filp, char __user *buf, size_t len, loff_t *off){ pr_info("Read function\n"); return 0; } /** * This function will be called when we write the Device file */ static ssize_t demo_timer_write(struct file *filp, const char __user *buf, size_t len, loff_t *off){ pr_info("Write function\n"); return len; } /** * Module Init function */ static int __init demo_timer_driver_init(void){ /*Allocating Major number*/ if(alloc_chrdev_region(&dev, 0, 1, "demo_timer_Dev") < 0 ){ pr_err("Cannot allocate major number\n"); return -1; } pr_info("Major = %d Minor = %d \n", MAJOR(dev), MINOR(dev)); /*Creating cdev structure*/ cdev_init(&demo_timer_cdev, &fops); /*Adding character device to the system*/ if((cdev_add(&demo_timer_cdev, dev, 1)) < 0){ pr_err("Cannot add the device to the system\n"); } /* setup your timer to call my_timer_callback */ timer_setup(&demo_timer, timer_callback, 0); //We can also use add_timer. /* setup timer interval to based on TIMEOUT Macro */ /* kernel timer should be in ticks or jiffs*/ mod_timer(&demo_timer, jiffies + msecs_to_jiffies(TIMEOUT)); pr_info("Device Driver Insert...Done!!!\n"); return 0; } /** * * Module exit function */ static void __exit demo_timer_driver_exit(void){ /* remove kernel when unloading module */ del_timer(&demo_timer); cdev_del(&demo_timer_cdev); unregister_chrdev_region(dev, 1); pr_info("Device Driver Remove...Done!!!\n"); } module_init(demo_timer_driver_init); module_exit(demo_timer_driver_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Junet Hossain"); MODULE_DESCRIPTION("A Simple kernel timer module");