Linux Kernel Driver Program: 6_File_opertions_device_driver
neelkanth_surekha#cat hello_world_module.c
/*************************************************************************
* neelkanth_surekha# sudo insmod hello_world_module.ko
* neelkanth_surekha# ls -lt /dev | grep dummy
* crw------- 1 root root 242, 0 Jan 26 13:54 dummy_device_device
*
* neelkanth_surekha# sudo rmmod hello_world_module.ko
* neelkanth_surekha# ls -lt /dev | grep dummy
*
***************************************************************************/
#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>
/* the dev_t for the char device to be added */
dev_t dev = 0;
/* pointer to the struct "class" that this device should be registered to */
static struct class *dev_class;
/* Character device structure */
static struct cdev dummy_device_cdev;
static int __init dummy_device_driver_init(void);
static void __exit dummy_device_driver_exit(void);
static int dummy_device_open(struct inode *inode, struct file *file);
static int dummy_device_release(struct inode *inode, struct file *file);
static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t dummy_device_write(struct file *filp, const char *buf, size_t len, loff_t * off);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = dummy_device_read,
.write = dummy_device_write,
.open = dummy_device_open,
.release = dummy_device_release,
};
static int dummy_device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Driver Open Function Called...!!!\n");
return 0;
}
static int dummy_device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Driver Release Function Called...!!!\n");
return 0;
}
static ssize_t dummy_device_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
printk(KERN_INFO "Driver Read Function Called...!!!\n");
return 0;
}
static ssize_t dummy_device_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
printk(KERN_INFO "Driver Write Function Called...!!!\n");
return len;
}
/*******************************************************************************************
* How Applications will communicate with Hardware device
*
* Step 1: Application
* Step 2: Device File or device Node
* Step 3: Major and Minor Number
* Step 4: Device Driver
* Step 5: Hardware
******************************************************************************************/
static int __init dummy_device_driver_init(void)
{
/* Allocating Major number */
if((alloc_chrdev_region(&dev, 0, 1, "dummy_device_Dev")) <0){
printk(KERN_INFO "Cannot allocate major number\n");
return -1;
}
printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
/*Creating cdev structure*/
/* In linux kernel struct "inode" structure is used to represent files. Therefore, it is
* different from the file structure that represents an "open file descriptor".
* There can be numerous file structures representing multiple open descriptors on a
* single file, but they all point to a single "inode" structure.
* The "inode" structure contains a great deal of information about the file. As a general
* rule, "cdev" structure is useful for writing driver code:
*/
cdev_init(&dummy_device_cdev, &fops);
dummy_device_cdev.owner = THIS_MODULE;
dummy_device_cdev.ops = &fops;
/*Adding character device to the system*/
if((cdev_add(&dummy_device_cdev, dev, 1)) < 0){
printk(KERN_INFO "Cannot add the device to the system\n");
goto r_class;
}
/*Creating struct class*/
/*
* This will create the struct class for our device driver.
* It will create structure under/sys/class/.
*/
if((dev_class = class_create(THIS_MODULE, "dummy_device_class")) == NULL){
printk(KERN_INFO "Cannot create the struct class\n");
goto r_class;
}
/*Creating device*/
/*
* This function can be used by char device classes. A struct device
* will be created in "sysfs", registered to the specified class.
*/
if((device_create(dev_class, NULL , dev, NULL, "dummy_device_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1\n");
goto r_device;
}
printk(KERN_INFO "Device Driver Insert...Done!!!\n");
return 0;
r_device:
class_destroy(dev_class);
r_class:
unregister_chrdev_region(dev,1);
return -1;
}
void __exit dummy_device_driver_exit(void)
{
device_destroy(dev_class, dev);
class_destroy(dev_class);
cdev_del(&dummy_device_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}
module_init(dummy_device_driver_init);
module_exit(dummy_device_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Neelkanth Reddy <www.neelkanth.13@gmail.com>");
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("0:1.0");
neelkanth_surekha#cat Makefile
obj-m += hello_world_module.oKDIR = /lib/modules/$(shell uname -r)/build
all:
make -C $(KDIR) M=$(shell pwd) modules
clean:
make -C $(KDIR) M=$(shell pwd) clean