Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

Learning Linux Device Drivers

Status
Not open for further replies.

codetrickster

Newbie level 3
Joined
Jan 8, 2014
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Location
Chennai, India
Activity points
41
I request all members to share some stuff related to Linux Device Driver Programming and we can have a discussion on each Drivers we share!!
Code:
/************************************************
************* Sample Device Driver  *************
*********  Tutorial -1 Character Driver Module **
**************  Date - 15/04/2013  **************
*************************************************/


#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/err.h>
#include <asm/uaccess.h>


#define device_major 240
#define DEV_NAME "char-device"
#define DEV_MINORS 1

#ifdef DEBUG
#define DEBUG(string,arg...) printk(KERN_DEBUG "DEBUG_MSG:"string,##arg)
#else
#define DEBUG(string,arg...)
#endif

dev_t dev_no;
struct class *sample_class;
struct device *sample_device;
struct cdev my_cdev[DEV_MINORS];
int device_flag = 0;
//char messsge[BUFF_LEN];
//char *message_ptr;


static int device_open(struct inode *inode, struct file *filp)
{
	if(device_flag)
		return -EBUSY;
	device_flag++;
	try_module_get(THIS_MODULE);
	return 0;
}

static int device_release(struct inode *inode, struct file * filp)
{
	device_flag--;
	module_put(THIS_MODULE);
	return 0;
}

static ssize_t device_read(struct file * filp, char __user *buffer, size_t length, loff_t *offset)
{
	
	return 0;
}

static ssize_t device_write(struct file * filp, const char __user *buffer, size_t length, loff_t *offset)
{
	return 0;
}

struct file_operations fops = {	
	.owner = THIS_MODULE,
	.read = device_read,
	.write = device_write,
	.open = device_open,
	.release = device_release,
};

static void simple_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops)
{
	int err, dev_no = MKDEV(device_major, minor);
	cdev_init(dev, fops);
	dev -> owner = THIS_MODULE;
	dev -> ops = fops;
	err = cdev_add(dev, dev_no, 1);
	if(err)
		DEBUG("Failed to add character device driver, STATUS = %d, MINOR = %d\n",err, minor);
}

static int __init sample_driver_init(void)
{
	int result;
	//void *ptr_err;
	dev_t dev = MKDEV(device_major, 0);
	result = register_chrdev_region(dev, 1, DEV_NAME);
	if(result < 0)	{
		DEBUG("Failed to get Device Major = %d with STATUS = %d\n", device_major, result);
		return result;
	}
//	if(device_major == 0)
//		device_major = result;

	DEBUG("Device created with Major %d\n", device_major);
	
	if(IS_ERR(sample_class = class_create(THIS_MODULE, DEV_NAME)))
		return PTR_ERR(sample_class);

	if(IS_ERR(sample_device = device_create(sample_class, NULL, 
					dev, NULL, DEV_NAME)))
		return PTR_ERR(sample_device);
	
	simple_setup_cdev(my_cdev, 0, &fops);
	return 0;
}

static void __exit sample_driver_exit(void)
{
	cdev_del(my_cdev);
	device_destroy(sample_class,MKDEV(device_major, 0));
	class_destroy(sample_class);
	unregister_chrdev_region(MKDEV(device_major, 0), 1);
	return;
}

module_init(sample_driver_init);
module_exit(sample_driver_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Tutorial-1 character Driver Module");
MODULE_AUTHOR("www.codetrickster.com");
This code is intended only for learning and has been referenced from various other sources.

Code:
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := char.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
endif
1. Copy the code to files with name char.c and Makefile(no extn) in a Linux Machine.
2. Build the Driver using the command make from the file location in the terminal.
3. issue insmod char.ko to insert the driver module and dmesg for kernel debug messages.
4. module inserted can be checked using lsmod which lists all inserted modules.
5. the character driver module is registered under /dev/char-device
6. removal of driver module is using rmmod char.ko

Note : All these have to be done from root user mode in a Linux Machine.

Updates and suggestions to the code are most welcomed.

Thanks and regards,
www.codetrickster.com
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top