ioctl作用:应用层的ioctl函数传入的cmd和arg参数会直接传入驱动层的ioctl接口,在对应驱动文件里会对相应的命令进行操作
对于传递的ioctl命令有一定的规范,具体可以参考:/include/asm/ioctl.h,/Documentation/ioctl-number.txt 这两个文件
构造ioctl命令linux已经给我们提供了宏命令:
_IO an ioctl with no parameters
_IOW an ioctl with write parameters (copy_from_user)
_IOR an ioctl with read parameters (copy_to_user)
_IOWR an ioctl with both write and read parameters
相关参数:
/*
type: 幻数(设备相关的一个字母,避免和内核冲突)
nr: 命令编号
datatype:数据类型
*/
_IO(type,nr) //无参数的命令
_IOR(type,nr,datatype) //应用从驱动中读数据
_IOW(type,nr,datatype) //应用从驱动中写数据
举一个简单的例子:
//应用程序
#define MOTOR_CMD_BASE'M'
#define SET_MOTOR_STEP _IOW(MOTOR_CMD_BASE, 1u, int)
#define GET_MOTOR_STEP _IOW(MOTOR_CMD_BASE, 2u, int)
...
int step= 0;
int value = 0;
int fd = -1;
fd = open("/dev/motor",O_RDWR);
if (fd== -1) {
printf("open device error!/n");
return 0;
}
.
.
printf("Please input the motor step:/n"
scanf("%d",&step);
if(ioctl(fd, SET_MOTOR_STEP, &step)<0){
perror("ioctl error");
exit(1);
}
if(ioctl(fd, GET_MOTOR_STEP, &value)<0){
perror("ioctl error");
exit(1);
}
...
//驱动程序
#define MOTOR_CMD_BASE'M'
#define SET_MOTOR_STEP _IOW(MOTOR_CMD_BASE, 1u, int)
#define GET_MOTOR_STEP _IOW(MOTOR_CMD_BASE, 2u, int)
int motor_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
int step=0;
int value = 0;
switch (cmd) {
case SET_MOTOR_STEP :
if(copy_from_user(&step, (int*)arg, sizeof(int)))
return fail;
//处理程序
break;
case GET_MOTOR_STEP :
value = 100;
if(copy_to_user((int*)arg, &value, sizeof(int)))
return fail;
break;
}