参考内核文档
新增ioctl 时, ioctl解析如下:
bits meaning
31-30 00 - no parameters: uses _IO macro
10 - read: _IOR
01 - write: _IOW
11 - read/write: _IOWR
29-16 size of arguments
15-8 ascii character supposedly
unique to each driver
7-0 function #
例如, 需要传入一个int值,读出一个int值, 可以如下实现:
#define EFUSE_IOCTL_READ _IOWR ('y', 0x1, int)
或者用一个数组,写入和读出各用一个int
#define EFUSE_IOCTL_READ _IOWR ('y', 0x1, int[2])
这个字母y 和数字 0x1 是根据内核文档里介绍,找一个没有使用的。这样能保证ioctl唯一性,在debug时有帮助。
static long test_efuse_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *ip = argp;
int addr = 0;
int val = 0;
switch (cmd) {
case EFUSE_IOCTL_READ:
if (get_user(addr, ip))
return -EFAULT;
if (addr >= 0 ) {
val = efuse_read(addr);
if (put_user(val, ip))
return -EFAULT;
return 0;
}
return -EINVAL;
default:
ERR_MSG("unknown ioctl command %d\n", cmd);
return -EINVAL;
}
return 0;
}
用户空间使用:
#define EFUSE_IOCTL_READ _IOWR ('y', 0x1, int)
file = open("/dev/test_efuse", O_RDWR);
if (file < 0) {
printf("open efuse device failed %d\n", errno);
return -ENODEV;
}
ret = ioctl(file, EFUSE_IOCTL_READ, &val);
if (ret < 0) {
perror("Unable to send data");
return ret;
}
close(file);