mirror of
https://github.com/Hizenberg469/Driver-tutorial.git
synced 2026-04-20 00:42:25 +03:00
driver-tutorial finished
This commit is contained in:
133
kernel_timer/demo_timer_driver.c
Normal file
133
kernel_timer/demo_timer_driver.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
//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");
|
||||
Reference in New Issue
Block a user