driver-tutorial finished

This commit is contained in:
2025-02-25 08:19:58 +00:00
parent 8a8b8cf56a
commit 9eed2d489b
17 changed files with 2393 additions and 0 deletions

View 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");