#include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> #include <linux/capability.h> #include <asm/uaccess.h> #include <linux/cdev.h> #include <linux/sem.h> #include <linux/vmalloc.h> #include <linux/ipc.h> #include <linux/delay.h> #include <linux/semaphore.h> int i,shmid; char a[10]=0; struct semaphore lock; static ssize_t sample_char_read(struct file * file, char __user * buf,size_t count, loff_t *ppos) { printk("sample_char2_read size(%ld)\n", count); return 0; } static ssize_t sample_char_write(struct file *filp, const char *buf,size_t size, loff_t *offp) { ///semaphore locking down(&lock); printk("sample_char_write size(%ld)\n", size); copy_from_user((void *) a,buf,size); printk("kernal=%s\n",a); msleep(5000); //semaphor unlock up(&lock); return size; } int sample_char_open(struct inode *inode, struct file *filp) { printk("sample_char_open\n"); //semaphore init sema_init(&lock, 1); return 0; } int sample_char_release(struct inode *inode, struct file *filp) { printk("sample_char_release\n"); return 0; } static struct file_operations sample_char_fops = { read:sample_char_read, write:sample_char_write, open:sample_char_open, release:sample_char_release, }; #define sample_major_number 89 #define max_minors 1 static struct cdev char_cdev; static dev_t dev; int init_module(void) { int ret = 0; dev = MKDEV(sample_major_number, 0); printk("\nLoading the sample char device driver\n"); ret = register_chrdev_region(dev,1, "sample_char"); if (ret) { printk("register_chrdev_region Error\n"); goto error; } cdev_init(&char_cdev, &sample_char_fops); ret = cdev_add(&char_cdev, dev,2); if (ret) { printk("cdev_add Error\n"); goto error_region; } return 0; error_region: unregister_chrdev_region(dev, max_minors); error: return ret; } void cleanup_module(void) { cdev_del(&char_cdev); unregister_chrdev_region(dev, max_minors); printk("\nUnloading the sample char device driver\n"); } TEST FILE #include<stdio.h> #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> int main(int argc ,char *argv[]) { char buf[100] ; char i = 0; int g; memset(buf, 0, 100); printf("Input: %s\n", argv[1]); int fp = open("/dev/sample_char", O_RDWR); if(fp<0) { perror("not sucess"); } i=fork(); if(i==0) { g=write(fp,argv[1], strlen(argv[1])); } else { g=write(fp,argv[2], strlen(argv[2])); wait(0); } } MAKE FILE obj-m += semaphore.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean test:app.c COMPILATION OF CODE gcc -o test app.c
Showing posts with label device driver. Show all posts
Showing posts with label device driver. Show all posts
Sunday, 18 May 2014
Character device driver using semaphore mechanism in linux
character device driver using MUTEX in linux
MUTEX DRIVER #include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> #include <linux/capability.h> #include <asm/uaccess.h> #include <linux/cdev.h> #include <linux/vmalloc.h> #include <linux/ipc.h> #include <linux/delay.h> #include <linux/mutex.h> int i,shmid; char *a; struct mutex lock; static ssize_t sample_char_read(struct file * file, char __user * buf,size_t count, loff_t *ppos) { printk("sample_char2_read size(%ld)\n", count); return 0; } static ssize_t sample_char_write(struct file *filp, const char *buf,size_t size, loff_t *offp) { //mutex lock mutex_lock(&lock); printk("sample_char_write size(%ld)\n", size); copy_from_user((void *)a,buf,size); printk("%s\n",a); msleep(3000); //mutex unlock mutex_unlock(&lock); return size; } int sample_char_open(struct inode *inode, struct file *filp) { printk("sample_char_open\n"); //mutex initialization mutex_init(&lock); a=(void *)vmalloc(20*sizeof(char)); return 0; } int sample_char_release(struct inode *inode, struct file *filp) { printk("sample_char_release\n"); return 0; } static struct file_operations sample_char_fops = { read: sample_char_read, write: sample_char_write, open: sample_char_open, release: sample_char_release, }; #define sample_major_number 89 #define max_minors 1 static struct cdev char_cdev; static dev_t dev; int init_module(void) { int ret = 0; dev = MKDEV(sample_major_number, 0); printk("\nLoading the sample char device driver\n"); ret = register_chrdev_region(dev,1, "sample_char"); if (ret) { printk("register_chrdev_region Error\n"); goto error; } cdev_init(&char_cdev, &sample_char_fops); ret = cdev_add(&char_cdev, dev,2); if (ret) { printk("cdev_add Error\n"); goto error_region; } return 0; error_region: unregister_chrdev_region(dev, max_minors); error: return ret; } void cleanup_module(void) { cdev_del(&char_cdev); unregister_chrdev_region(dev, max_minors); printk("\nUnloading the sample char device driver\n"); } APPLICATION FILE #include<stdio.h> #include <fcntl.h> #include <assert.h> #include <string.h> // for memset and strlen #include<sys/types.h> #include<sys/stat.h> int main(int argc ,char *argv[]) { // assert(argc > 1);//abort program if assertion is false char buf[100] ; char i = 0; int g; memset(buf, 0, 100); printf("Input: %s\n", argv[1]); int fp = open("/dev/sample_mutex", O_RDWR); if(fp<0) { perror("not sucess"); } i=fork(); if(i==0) { g=write(fp,argv[1], strlen(argv[1])); } else { g=write(fp,argv[2], strlen(argv[2])); wait(0); } }
Sleeping mechanism in character driver in linux
#include <linux/module.h> #include <linux/fs.h> //various structures(fops) #include <linux/major.h> #include <linux/capability.h> #include <asm/uaccess.h> //copy_to/from_user() #include <linux/cdev.h> //cdev #include <linux/wait.h> //wait queues #include <linux/sched.h> //Task states (TASK_INTERRUPTIBLE etc) wait_queue_head_t queue; int flag = 0; static ssize_t sample_char_read(struct file * file, char __user * buf,size_t count, loff_t *ppos) { flag = 0; wait_event_interruptible(queue, flag == 1); printk("sample_char_read size(%ld)\n", count); return 0; } static ssize_t sample_char_write(struct file *filp, const char *buf,size_t size, loff_t *offp) { flag = 1; wake_up_interruptible(&queue); printk("sample_char_write size(%ld)\n", size); return size; } int sample_char_open(struct inode *inode, struct file *filp) { printk("sample_char_open\n"); return 0; } int sample_char_release(struct inode *inode, struct file *filp) { printk("sample_char_release\n"); return 0; } static struct file_operations sample_char_fops = { .read= sample_char_read, .write= sample_char_write, .open= sample_char_open, .release= sample_char_release, }; #define sample_major_number 249 #define max_minors 1 static struct cdev char_cdev; static dev_t dev; int init_module(void) { int ret = 0; dev = MKDEV(sample_major_number, 0); printk("\nLoading the sample char device driver\n"); ret = register_chrdev_region(dev, max_minors, "sample_char"); if (ret) { printk("register_chrdev_region Error\n"); goto error; } cdev_init(&char_cdev, &sample_char_fops); ret = cdev_add(&char_cdev, dev, max_minors); if (ret) { printk("cdev_add Error\n"); goto error_region; } init_waitqueue_head(&queue); return 0; error_region: unregister_chrdev_region(dev, max_minors); error: return ret; } void cleanup_module(void) { cdev_del(&char_cdev); unregister_chrdev_region(dev, max_minors); printk("\nUnloading the sample char device driver\n"); }
Memory allocation using kmalloc in character driver in linux
#include <linux/module.h> #include <linux/fs.h> //various structures(fops) #include <linux/major.h> #include <linux/capability.h> #include <asm/uaccess.h> //copy_to/from_user() #include <linux/cdev.h> //cdev #include <linux/sched.h> //Task states (TASK_INTERRUPTIBLE etc) #include <linux/slab.h> //kmalloc/kfree char *ptr; #define BUF_SIZE PAGE_SIZE static ssize_t sample_char_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { int err; printk("sample_char_read size(%ld)\n", count); err = copy_to_user((void *) buf, file->private_data, count); if (err) err = -EFAULT; return count; } static ssize_t sample_char_write(struct file *file, const char *buf, size_t size, loff_t *offp) { printk("sample_char_write size(%ld)\n", size); copy_from_user( (void *)file->private_data , buf, size); printk("in private =%s",file->private_data); return size; } int sample_char_open(struct inode *inode, struct file *filp) { printk("sample_char_open\n"); filp->private_data = ptr; return 0; } int sample_char_release(struct inode *inode, struct file *filp) { kfree (ptr); printk("sample_char_release\n"); return 0; } static struct file_operations sample_char_fops = { read: sample_char_read, write: sample_char_write, open: sample_char_open, release: sample_char_release, }; #define sample_major_number 249 #define max_minors 1 static struct cdev char_cdev; static dev_t dev; int init_module(void) { int ret = 0; dev = MKDEV(sample_major_number, 0); printk("\nLoading the sample char device driver\n"); ret = register_chrdev_region(dev, max_minors, "sample_char"); if (ret) { printk("register_chrdev_region Error\n"); goto error; } cdev_init(&char_cdev, &sample_char_fops); ret = cdev_add(&char_cdev, dev, max_minors); if (ret) { printk("cdev_add Error\n"); goto error_region; } ptr = kmalloc(BUF_SIZE, GFP_KERNEL); if (!ptr) { pr_info("unable to get memory block\n"); ret = -ENOMEM; goto error_region; } memset (ptr, 0, BUF_SIZE); return 0; error_region: unregister_chrdev_region(dev, max_minors); error: return ret; } void cleanup_module(void) { cdev_del(&char_cdev); unregister_chrdev_region(dev, max_minors); printk("\nUnloading the sample char device driver\n"); }
misc character driver using IOCTL call in linux
#include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> #include <linux/capability.h> #include <asm/uaccess.h> #include <linux/miscdevice.h> #include <linux/ioctl.h> struct test_ioctl { int cmd_no; char data[64]; }; #define SAMPLE_IOCTL_MAGIC_NUMBER 's' #define SAMPLE_IOCTL_CMD_1 \ _IOR(SAMPLE_IOCTL_MAGIC_NUMBER, 0x1, int) #define SAMPLE_IOCTL_CMD_2 \ _IOW(SAMPLE_IOCTL_MAGIC_NUMBER, 0x2, int) #define SAMPLE_IOCTL_CMD_3 \ _IO(SAMPLE_IOCTL_MAGIC_NUMBER, 0x3) #define SAMPLE_IOCTL_CMD_4 \ _IOWR(SAMPLE_IOCTL_MAGIC_NUMBER, 0x4, struct test_ioctl) static ssize_t sample_char_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { printk("sample_char_read size(%ld)\n", count); return 0; } static ssize_t sample_char_write(struct file *filp, const char *buf, size_t size, loff_t *offp) { printk("sample_char_write size(%ld)\n", size); return size; } int sample_char_open(struct inode *inode, struct file *filp) { printk("sample_char_open\n"); return 0; } int sample_char_release(struct inode *inode, struct file *filp) { printk("sample_char_release\n"); return 0; } int sample_char_ioctl (struct file *filp,unsigned int cmd, unsigned long arg) { int ret = 0; printk("sample_char_ioctl\n"); switch (cmd) { case SAMPLE_IOCTL_CMD_1: printk("IOCTL CMD1\n"); /*Do Something*/ break; case SAMPLE_IOCTL_CMD_2: printk("IOCTL CMD2\n"); /*Do Something*/ break; case SAMPLE_IOCTL_CMD_3: printk("IOCTL CMD3\n"); /*Do Something*/ break; case SAMPLE_IOCTL_CMD_4: printk("IOCTL CMD4\n"); /*Do Something*/ break; default: /*Default option*/ /*Do Something or return invalid command error*/ printk("Invalid IOCTL CMD\n"); ret = -EINVAL; } return ret; } static struct file_operations sample_char_fops = { read: sample_char_read, write: sample_char_write, open: sample_char_open, release: sample_char_release, unlocked_ioctl: sample_char_ioctl, }; static struct miscdevice misc_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "sample_misc_dev", .fops = &sample_char_fops, .mode = S_IRWXUGO, }; int init_module(void) { int ret = 0; printk("\nLoading the sample misc char device driver\n"); ret = misc_register(&misc_dev); if (ret) printk("Unable to register misc dev\n"); return ret; } void cleanup_module(void) { printk("\nUnloading the sample char device driver\n"); misc_deregister(&misc_dev); } TEST FILE #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <errno.h> struct test_ioctl { int cmd_no; char data[64]; }; #define SAMPLE_IOCTL_MAGIC_NUMBER 's' #define SAMPLE_IOCTL_CMD_1 \ _IOR(SAMPLE_IOCTL_MAGIC_NUMBER, 0x1, int) #define SAMPLE_IOCTL_CMD_2 \ _IOW(SAMPLE_IOCTL_MAGIC_NUMBER, 0x2, int) #define SAMPLE_IOCTL_CMD_3 \ _IO(SAMPLE_IOCTL_MAGIC_NUMBER, 0x3) #define SAMPLE_IOCTL_CMD_4 \ _IOWR(SAMPLE_IOCTL_MAGIC_NUMBER, 0x4, struct test_ioctl) int main() { int fd, ret = 0, val = 10; fd = open("/dev/sample_misc_dev", O_RDWR); printf("file descriptor fd(%d)\n", fd); if (fd < 0) { printf("File open error\n"); } printf("Sending ioctl CMD 3\n"); ret = ioctl(fd, SAMPLE_IOCTL_CMD_3); printf("ioctl ret val (%d) errno (%d)\n", ret, errno); perror("IOCTL error: "); printf("Sending ioctl CMD 2\n"); ret = ioctl(fd, SAMPLE_IOCTL_CMD_2, &val); printf("ioctl ret val (%d) errno (%d)\n", ret, errno); perror("IOCTL error: "); close(fd); }
Subscribe to:
Posts (Atom)