感觉里面有点东西,粗暴的理解一下:
(两个函数都是写在内核里面的,to是发送数据给用户,from是从用户接收)
copy_to_user函数原型
static inline long copy_to_user(void __user *to,const void *from, unsigned long n)
{}
/*
###void __user *to:一个地址,接收的地址,__user好像是用来校验的,他自己解决,不管他
###const void *from:数据
###unsigned long n:个人理解是其他参数,我传的结构体大小
*/
/*
我是在ioctl函数中使用的,要先在
struct file_operations cdev_fops = {
.open = char_open, /*open方法*/
.release = char_release, /*close*/
.unlocked_ioctl = char_ioctl,
};
定义char_ioctl方法
*/
用户直接使用ioctl函数如下
ret = ioctl(fd,0,(long)&gyrodata);
内核使用ioctl函数如下
long char_ioctl(struct file *file, unsigned int cmd, unsigned long args)
{
int ret;
printk("get GYRO x%05d y%05d z%05d ioctl###\n",__func__,__LINE__,gyrodata.x,gyrodata.y,gyrodata.z);
ret = copy_to_user((void *)args,&gyrodata,sizeof(gyrodata));
return 0;
}
用户ioctl函数原型
ioctl(int fd,int cmd,...),下面具体介绍我传的三个参数
###fd:fd = open("/dev/gyro0",O_RDWR);这是字符设备驱动里创建的文件夹
###0:用户传输的指令,可以在内核使用实现相关功能
###(long)&gyrodata:我在这里传了个结构体地址,想把数据通过结构体传给用户
再说我用的copy_to_user((void *)args,&gyrodata,sizeof(gyrodata));
这些在函数传参的时候都有,所以就直接使用了,包括(void *)args结构体地址,&gyrodata数据,结构体大小
copy_from_user函数原型
static inline long copy_from_user(void *to,
const void __user * from, unsigned long n)
{
might_sleep();
if (access_ok(VERIFY_READ, from, n))
return __copy_from_user(to, from, n);
else
return n;
}
其实都差不多了。这俩函数不一定在ioctl里面用,只要能找到合适的参数,都是可以使用的,比如fops里面的read方法里的char __user *usr 参数就可以用来作为to 和 from的第一个参数。