linux如何通过ioctl调用驱动的

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;
}  

猜你喜欢

转载自blog.csdn.net/q2519008/article/details/83180404