calculator using ioctl of linux device driver











up vote
0
down vote

favorite












I am learning linux device drivers



So i am trying to write a code for calculator where user will give input using userspace program but the calculations will happen in kernel



I am using ioctl to pass values to kernel



It works fine first time(i.e. after inserting the device driver) ,but after that it gives incorrect output. So if i again want correct answer i do rmmod driver and again insmod driver



Whats wrong with the code ?



Is there any better way to map operation ,value1 and value2 than using the count variable as i am using in driver code



following is the output
where first time i get the correct output,but the second time a garbage value:



calculator_ioctl$ ./a.out 

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is 34
closing driver

calculator_ioctl$ ./a.out

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is -1410510832
closing driver


driver code:



#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/slab.h> //kmalloc.h
#include<linux/uaccess.h> //copy to/from user
#include<linux/ioctl.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int32_t value1 = 0 ;
int32_t value2 = 0 ;
int32_t value = 0 ;
int32_t oper = 0 ;
dev_t dev=0;
static struct class *dev_class;
static struct cdev etx_cdev ;

static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg);





static struct file_operations fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = etx_ioctl,

};


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
static int count = 0;
switch(cmd) {

case WR_VALUE:
if(count == 0)
{
copy_from_user(&oper,(int32_t*)arg,sizeof(oper));
printk(KERN_INFO "oper = %dn",oper);
break;

}
else if(count == 1){
copy_from_user(&value1,(int32_t*)arg,sizeof(value1));
printk(KERN_INFO "value1 = %dn",value1);
break;

}
else if(count == 2){
copy_from_user(&value2,(int32_t*)arg,sizeof(value2));
printk(KERN_INFO "value2 = %dn",value2);
break;

}
case RD_VALUE:
if(oper == 1)
value = value1 + value2 ;
else if(oper == 2)
value = value1 - value2;
else if(oper == 3)
value = value1 * value2;
else if(oper == 4)
value = value1 / value2;
else
break;
copy_to_user((int32_t*) arg, &value,sizeof(value));
break;
}

count+=1 ;
if(count == 3)
count = 0 ;

return 0;
}

static int __init etx_driver_init(void)
{
if((alloc_chrdev_region(&dev,0,1,"etx_dev")) <0){
printk(KERN_INFO"cannot allocate major numbern");
return -1;
}
printk(KERN_INFO " MAJOR = %d Minor = %dn",MAJOR(dev),MINOR(dev));


cdev_init(&etx_cdev,&fops);


if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "cannot add device to the systemn");
goto r_class;
}

/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct classn");
goto r_class;
}

/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1n");
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 etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!n");
}

module_init(etx_driver_init);
module_exit(etx_driver_exit);


MODULE_LICENSE("GPL");


application:



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>


#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int main()
{ int num;
int fd;
int32_t value,number1,number2,output,operation;
printf("n*************************************n");

printf("nOpening Drivern");

fd = open("/dev/etx_device",O_RDWR);
if(fd<0) {
printf("Cannot open device file ...n");
return 0;
}

printf("Operation to performnn");
printf("
1. Add n
2. Subtract n
3. Multiply n
4. Divide nnn ");


scanf("%d",&num);
if(num > 4 && num < 1)
{
printf("Enter between 1 and 4");
return 0;
}
ioctl(fd,WR_VALUE,(int32_t*) &num);

printf("Enter first value :");
scanf("%d",&number1);

printf("Enter second value :");
scanf("%d",&number2);
printf("writing value to drivern");

ioctl(fd,WR_VALUE,(int32_t*) &number1);
ioctl(fd,WR_VALUE,(int32_t*) &number2);

printf("Reading value from driver n");
ioctl(fd,RD_VALUE,(int32_t*)&value);
printf("value is %dn",value);

printf("closing drivern");
close(fd);

}









share|improve this question
























  • Have you been trying to do a proper error checking and handling?
    – 0andriy
    Nov 21 at 8:07










  • No ,just trying to learn how to use ioctl
    – ra-one
    Nov 21 at 9:22






  • 1




    You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
    – Tsyvarev
    Dec 8 at 10:30















up vote
0
down vote

favorite












I am learning linux device drivers



So i am trying to write a code for calculator where user will give input using userspace program but the calculations will happen in kernel



I am using ioctl to pass values to kernel



It works fine first time(i.e. after inserting the device driver) ,but after that it gives incorrect output. So if i again want correct answer i do rmmod driver and again insmod driver



Whats wrong with the code ?



Is there any better way to map operation ,value1 and value2 than using the count variable as i am using in driver code



following is the output
where first time i get the correct output,but the second time a garbage value:



calculator_ioctl$ ./a.out 

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is 34
closing driver

calculator_ioctl$ ./a.out

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is -1410510832
closing driver


driver code:



#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/slab.h> //kmalloc.h
#include<linux/uaccess.h> //copy to/from user
#include<linux/ioctl.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int32_t value1 = 0 ;
int32_t value2 = 0 ;
int32_t value = 0 ;
int32_t oper = 0 ;
dev_t dev=0;
static struct class *dev_class;
static struct cdev etx_cdev ;

static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg);





static struct file_operations fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = etx_ioctl,

};


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
static int count = 0;
switch(cmd) {

case WR_VALUE:
if(count == 0)
{
copy_from_user(&oper,(int32_t*)arg,sizeof(oper));
printk(KERN_INFO "oper = %dn",oper);
break;

}
else if(count == 1){
copy_from_user(&value1,(int32_t*)arg,sizeof(value1));
printk(KERN_INFO "value1 = %dn",value1);
break;

}
else if(count == 2){
copy_from_user(&value2,(int32_t*)arg,sizeof(value2));
printk(KERN_INFO "value2 = %dn",value2);
break;

}
case RD_VALUE:
if(oper == 1)
value = value1 + value2 ;
else if(oper == 2)
value = value1 - value2;
else if(oper == 3)
value = value1 * value2;
else if(oper == 4)
value = value1 / value2;
else
break;
copy_to_user((int32_t*) arg, &value,sizeof(value));
break;
}

count+=1 ;
if(count == 3)
count = 0 ;

return 0;
}

static int __init etx_driver_init(void)
{
if((alloc_chrdev_region(&dev,0,1,"etx_dev")) <0){
printk(KERN_INFO"cannot allocate major numbern");
return -1;
}
printk(KERN_INFO " MAJOR = %d Minor = %dn",MAJOR(dev),MINOR(dev));


cdev_init(&etx_cdev,&fops);


if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "cannot add device to the systemn");
goto r_class;
}

/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct classn");
goto r_class;
}

/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1n");
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 etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!n");
}

module_init(etx_driver_init);
module_exit(etx_driver_exit);


MODULE_LICENSE("GPL");


application:



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>


#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int main()
{ int num;
int fd;
int32_t value,number1,number2,output,operation;
printf("n*************************************n");

printf("nOpening Drivern");

fd = open("/dev/etx_device",O_RDWR);
if(fd<0) {
printf("Cannot open device file ...n");
return 0;
}

printf("Operation to performnn");
printf("
1. Add n
2. Subtract n
3. Multiply n
4. Divide nnn ");


scanf("%d",&num);
if(num > 4 && num < 1)
{
printf("Enter between 1 and 4");
return 0;
}
ioctl(fd,WR_VALUE,(int32_t*) &num);

printf("Enter first value :");
scanf("%d",&number1);

printf("Enter second value :");
scanf("%d",&number2);
printf("writing value to drivern");

ioctl(fd,WR_VALUE,(int32_t*) &number1);
ioctl(fd,WR_VALUE,(int32_t*) &number2);

printf("Reading value from driver n");
ioctl(fd,RD_VALUE,(int32_t*)&value);
printf("value is %dn",value);

printf("closing drivern");
close(fd);

}









share|improve this question
























  • Have you been trying to do a proper error checking and handling?
    – 0andriy
    Nov 21 at 8:07










  • No ,just trying to learn how to use ioctl
    – ra-one
    Nov 21 at 9:22






  • 1




    You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
    – Tsyvarev
    Dec 8 at 10:30













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am learning linux device drivers



So i am trying to write a code for calculator where user will give input using userspace program but the calculations will happen in kernel



I am using ioctl to pass values to kernel



It works fine first time(i.e. after inserting the device driver) ,but after that it gives incorrect output. So if i again want correct answer i do rmmod driver and again insmod driver



Whats wrong with the code ?



Is there any better way to map operation ,value1 and value2 than using the count variable as i am using in driver code



following is the output
where first time i get the correct output,but the second time a garbage value:



calculator_ioctl$ ./a.out 

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is 34
closing driver

calculator_ioctl$ ./a.out

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is -1410510832
closing driver


driver code:



#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/slab.h> //kmalloc.h
#include<linux/uaccess.h> //copy to/from user
#include<linux/ioctl.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int32_t value1 = 0 ;
int32_t value2 = 0 ;
int32_t value = 0 ;
int32_t oper = 0 ;
dev_t dev=0;
static struct class *dev_class;
static struct cdev etx_cdev ;

static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg);





static struct file_operations fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = etx_ioctl,

};


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
static int count = 0;
switch(cmd) {

case WR_VALUE:
if(count == 0)
{
copy_from_user(&oper,(int32_t*)arg,sizeof(oper));
printk(KERN_INFO "oper = %dn",oper);
break;

}
else if(count == 1){
copy_from_user(&value1,(int32_t*)arg,sizeof(value1));
printk(KERN_INFO "value1 = %dn",value1);
break;

}
else if(count == 2){
copy_from_user(&value2,(int32_t*)arg,sizeof(value2));
printk(KERN_INFO "value2 = %dn",value2);
break;

}
case RD_VALUE:
if(oper == 1)
value = value1 + value2 ;
else if(oper == 2)
value = value1 - value2;
else if(oper == 3)
value = value1 * value2;
else if(oper == 4)
value = value1 / value2;
else
break;
copy_to_user((int32_t*) arg, &value,sizeof(value));
break;
}

count+=1 ;
if(count == 3)
count = 0 ;

return 0;
}

static int __init etx_driver_init(void)
{
if((alloc_chrdev_region(&dev,0,1,"etx_dev")) <0){
printk(KERN_INFO"cannot allocate major numbern");
return -1;
}
printk(KERN_INFO " MAJOR = %d Minor = %dn",MAJOR(dev),MINOR(dev));


cdev_init(&etx_cdev,&fops);


if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "cannot add device to the systemn");
goto r_class;
}

/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct classn");
goto r_class;
}

/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1n");
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 etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!n");
}

module_init(etx_driver_init);
module_exit(etx_driver_exit);


MODULE_LICENSE("GPL");


application:



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>


#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int main()
{ int num;
int fd;
int32_t value,number1,number2,output,operation;
printf("n*************************************n");

printf("nOpening Drivern");

fd = open("/dev/etx_device",O_RDWR);
if(fd<0) {
printf("Cannot open device file ...n");
return 0;
}

printf("Operation to performnn");
printf("
1. Add n
2. Subtract n
3. Multiply n
4. Divide nnn ");


scanf("%d",&num);
if(num > 4 && num < 1)
{
printf("Enter between 1 and 4");
return 0;
}
ioctl(fd,WR_VALUE,(int32_t*) &num);

printf("Enter first value :");
scanf("%d",&number1);

printf("Enter second value :");
scanf("%d",&number2);
printf("writing value to drivern");

ioctl(fd,WR_VALUE,(int32_t*) &number1);
ioctl(fd,WR_VALUE,(int32_t*) &number2);

printf("Reading value from driver n");
ioctl(fd,RD_VALUE,(int32_t*)&value);
printf("value is %dn",value);

printf("closing drivern");
close(fd);

}









share|improve this question















I am learning linux device drivers



So i am trying to write a code for calculator where user will give input using userspace program but the calculations will happen in kernel



I am using ioctl to pass values to kernel



It works fine first time(i.e. after inserting the device driver) ,but after that it gives incorrect output. So if i again want correct answer i do rmmod driver and again insmod driver



Whats wrong with the code ?



Is there any better way to map operation ,value1 and value2 than using the count variable as i am using in driver code



following is the output
where first time i get the correct output,but the second time a garbage value:



calculator_ioctl$ ./a.out 

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is 34
closing driver

calculator_ioctl$ ./a.out

*************************************

Opening Driver
Operation to perform

1. Add
2. Subtract
3. Multiply
4. Divide


2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is -1410510832
closing driver


driver code:



#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/slab.h> //kmalloc.h
#include<linux/uaccess.h> //copy to/from user
#include<linux/ioctl.h>

#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int32_t value1 = 0 ;
int32_t value2 = 0 ;
int32_t value = 0 ;
int32_t oper = 0 ;
dev_t dev=0;
static struct class *dev_class;
static struct cdev etx_cdev ;

static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg);





static struct file_operations fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = etx_ioctl,

};


static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
static int count = 0;
switch(cmd) {

case WR_VALUE:
if(count == 0)
{
copy_from_user(&oper,(int32_t*)arg,sizeof(oper));
printk(KERN_INFO "oper = %dn",oper);
break;

}
else if(count == 1){
copy_from_user(&value1,(int32_t*)arg,sizeof(value1));
printk(KERN_INFO "value1 = %dn",value1);
break;

}
else if(count == 2){
copy_from_user(&value2,(int32_t*)arg,sizeof(value2));
printk(KERN_INFO "value2 = %dn",value2);
break;

}
case RD_VALUE:
if(oper == 1)
value = value1 + value2 ;
else if(oper == 2)
value = value1 - value2;
else if(oper == 3)
value = value1 * value2;
else if(oper == 4)
value = value1 / value2;
else
break;
copy_to_user((int32_t*) arg, &value,sizeof(value));
break;
}

count+=1 ;
if(count == 3)
count = 0 ;

return 0;
}

static int __init etx_driver_init(void)
{
if((alloc_chrdev_region(&dev,0,1,"etx_dev")) <0){
printk(KERN_INFO"cannot allocate major numbern");
return -1;
}
printk(KERN_INFO " MAJOR = %d Minor = %dn",MAJOR(dev),MINOR(dev));


cdev_init(&etx_cdev,&fops);


if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "cannot add device to the systemn");
goto r_class;
}

/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct classn");
goto r_class;
}

/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1n");
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 etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!n");
}

module_init(etx_driver_init);
module_exit(etx_driver_exit);


MODULE_LICENSE("GPL");


application:



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>


#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)


int main()
{ int num;
int fd;
int32_t value,number1,number2,output,operation;
printf("n*************************************n");

printf("nOpening Drivern");

fd = open("/dev/etx_device",O_RDWR);
if(fd<0) {
printf("Cannot open device file ...n");
return 0;
}

printf("Operation to performnn");
printf("
1. Add n
2. Subtract n
3. Multiply n
4. Divide nnn ");


scanf("%d",&num);
if(num > 4 && num < 1)
{
printf("Enter between 1 and 4");
return 0;
}
ioctl(fd,WR_VALUE,(int32_t*) &num);

printf("Enter first value :");
scanf("%d",&number1);

printf("Enter second value :");
scanf("%d",&number2);
printf("writing value to drivern");

ioctl(fd,WR_VALUE,(int32_t*) &number1);
ioctl(fd,WR_VALUE,(int32_t*) &number2);

printf("Reading value from driver n");
ioctl(fd,RD_VALUE,(int32_t*)&value);
printf("value is %dn",value);

printf("closing drivern");
close(fd);

}






linux-device-driver ioctl






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 8:32

























asked Nov 20 at 6:03









ra-one

396




396












  • Have you been trying to do a proper error checking and handling?
    – 0andriy
    Nov 21 at 8:07










  • No ,just trying to learn how to use ioctl
    – ra-one
    Nov 21 at 9:22






  • 1




    You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
    – Tsyvarev
    Dec 8 at 10:30


















  • Have you been trying to do a proper error checking and handling?
    – 0andriy
    Nov 21 at 8:07










  • No ,just trying to learn how to use ioctl
    – ra-one
    Nov 21 at 9:22






  • 1




    You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
    – Tsyvarev
    Dec 8 at 10:30
















Have you been trying to do a proper error checking and handling?
– 0andriy
Nov 21 at 8:07




Have you been trying to do a proper error checking and handling?
– 0andriy
Nov 21 at 8:07












No ,just trying to learn how to use ioctl
– ra-one
Nov 21 at 9:22




No ,just trying to learn how to use ioctl
– ra-one
Nov 21 at 9:22




1




1




You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
– Tsyvarev
Dec 8 at 10:30




You program should be run when counter value is 0. When you write the second value (with WR_VALUE code), your counter becomes 0. After that, your read the result (with RD_VALUE code), and you counter is updated again, and becomes 1. It is incorrect state for run a program again. You probably want to NOT update the counter in RD_VALUE case.
– Tsyvarev
Dec 8 at 10:30

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387116%2fcalculator-using-ioctl-of-linux-device-driver%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387116%2fcalculator-using-ioctl-of-linux-device-driver%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Ottavio Pratesi

Tricia Helfer

15 giugno