1. 程式人生 > >linux如何通過ioctl呼叫驅動的

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