2017-02-27 2 views
0

J'ai écrit un pilote IOCTL et une application ioctl correspondante avec un fichier d'en-tête contenant des commandes.L'appel IOCTL ne fonctionne pas avec le pilote

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kdev_t.h> 
#include <linux/types.h> 
#include <linux/fs.h> 
#include <linux/cdev.h> 
#include <asm/uaccess.h> 
#include "myioctl.h" 
#include <linux/ioctl.h> 



#define NAME MyCharDevice 


//Function Prototypes 
int NAME_open(struct inode *inode, struct file *filp); 
int NAME_release(struct inode *indoe, struct file *filp); 
ssize_t NAME_write(struct file *filp, char __user *Ubuff, size_t count, loff_t *offp); 
ssize_t NAME_read(struct file *filp, char __user *Ubuff, size_t count, loff_t *offp); 
int NAME_flush (struct file *filp); 
int NAME_IOCTL (struct inode *inode, struct file *filp, unsigned long cmd, unsigned long val); 



//Structure that defines the operations that the driver provides 
struct file_operations fops = 
{ 
    .owner = THIS_MODULE, 
    .open = NAME_open, 
    .read = NAME_read, 
    .write = NAME_write, 
    .unlocked_ioctl = NAME_IOCTL, 
    .release = NAME_release, 
    .flush = NAME_flush, 
}; 

//Structure for a character driver 
struct cdev *my_cdev; 


//Init Module 
static int __init CharDevice_init(void) 
{ 
    int result; 
    int MAJOR,MINOR; 
    dev_t Mydev; 
    Mydev = MKDEV(255,0);//Create a device number 
    MAJOR=MAJOR(Mydev); 
    MINOR=MINOR(Mydev); 
    printk("\nThe Major Number is %d...THe Minor Number is %d\n",MAJOR,MINOR); 
    result=register_chrdev_region(Mydev,1,"MyCharDevice");//register device region..... 
    if(result<0) 
    { 
     printk(KERN_ALERT "\nThe Region requested for is not obtainable\n"); 
     return(-1); 
    } 

    my_cdev = cdev_alloc();//allocate memory to Char Device structure 
    my_cdev->ops = &fops;//link our file operations to the char device 

    result=cdev_add(my_cdev,Mydev,1);//Notify the kernel abt the new device 
    if(result<0) 
    { 
     printk(KERN_ALERT "\nThe Char Devide has not been created......\n"); 
     return (-1); 
    } 
    return 0; 
} 


//Cleanup Module 
void __exit CharDevice_exit(void) 
{ 
    dev_t Mydev; 
    int MAJOR,MINOR; 
    Mydev=MKDEV(255,0); 
    MAJOR=MAJOR(Mydev); 
    MINOR=MINOR(Mydev); 
    printk("\nThe Major Number is %d...THe Minor Number is %d\n",MAJOR,MINOR); 
    unregister_chrdev_region(Mydev,1);//unregister the device numbers and the device created 
    cdev_del(my_cdev); 
    printk(KERN_ALERT "\nI have unregistered the stuff that was allocated.....Goodbye for ever.....\n"); 
    return; 
} 

int NAME_IOCTL (struct inode *inode, struct file *filp, unsigned long cmd, unsigned long val) 
{ 
    int BAUD=0, STOP; 
    char PARITY, CONFIG; 
printk ("In IOCTL\n"); 
printk("command = %d %d val = %d\n", cmd, SET_BAUD, val); 
    switch (cmd) { 

     case SET_BAUD: 
      get_user (BAUD, (int *)val);  
      printk ("The baud is %d", BAUD); 

     case SET_PARITY: 


     case SET_STOP: 


     case READ_CONFIG: 


     default: 
      return -1; 
    } 
    return 0; 
} 

//Open System Call 
int NAME_open(struct inode *inode, struct file *filp) 
{ 
    printk(KERN_ALERT "\nThis is the Kernel....Open Call.....I have nothing to do.....but YOU ALL HAVE....HAHAHAHA...\n"); 
    return 0; 
} 

//Close System Call 
int NAME_release(struct inode *indoe, struct file *filp) 
{ 
    printk(KERN_ALERT "\nThis is the release method of my Character Driver......Bye Dudes......\n"); 
    return 0; 
} 


//Write Functionality 
ssize_t NAME_write(struct file *filp, char __user *Ubuff, size_t count, loff_t *offp) 
{ 
    char Kbuff[80]; 
    unsigned long result; 
    ssize_t retval; 
    //strcpy(Kbuff,Ubuff); 
    result=copy_from_user((char *)Kbuff,(char *)Ubuff,count); //get user data 
    if(result==0) 
    { 
     printk(KERN_ALERT "\nMessage from the user......\n>>>> %s <<<<\n",Kbuff); 
     printk(KERN_ALERT "\n Data Successfully Written.....\n"); 
     retval=count; 
     return retval; 
    } 
    else 
    { 
     printk(KERN_ALERT "\n Error Writing Data\n"); 
     retval=-EFAULT; 
     return retval; 
    } 
} 

//read Functionality  
ssize_t NAME_read(struct file *filp, char __user *Ubuff, size_t count, loff_t *offp) 
{ 
    char Kbuff[]="THis is some date from the kernel to the user....User,ENJOY......"; 
    unsigned long result; 
    ssize_t retval; 
    //strcpy(Kbuff,Ubuff); 
    result=copy_to_user((char *)Ubuff,(char *)Kbuff,sizeof(Kbuff)); //copy to user 
    if(result==0) 
    { 
     //printk("\nMessage from the user......\n>>>> %s <<<<\n"); 
     printk(KERN_ALERT "\n Data Successfully read.....\n"); 
     retval=count; 
     return retval; 
    } 
    else 
    { 
     printk(KERN_ALERT"\n Error Writing Data to User\n"); 
     retval=-EFAULT; 
     return retval; 
    } 
} 

int NAME_flush (struct file *filp) 
{ 
    printk("\n This is the close function of the file...."); 
    return 0; 
} 

//Module over ride functions 
module_init(CharDevice_init); 
module_exit(CharDevice_exit); 

fichier d'en-tête

#define MAGIC 'x' 

#define SET_BAUD _IOW(MAGIC,0, int) 
#define SET_PARITY _IOW(MAGIC, 1, char) 
#define SET_STOP _IOW(MAGIC, 2, int) 
#define READ_CONFIG _IOR(MAGIC, 3, int) 

fichier c

#include <stdio.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <linux/ioctl.h> 
#include "myioctl.h" 
int main() 
{ 
    int FileDesc, Baud=9600; 
// char Ubuff[]="THis is the User Buffer......Sending Data to the Kernel...."; 
// char Kbuff[100];  
    FileDesc=open("/dev/MyCharDevice",O_RDWR); 
    if(FileDesc <0) 
    { 
     printf("\nError Opening Device\n"); 
     exit(1); 
    } 
    ioctl (FileDesc, SET_BAUD, &Baud); 
    printf("%d %d \n", SET_BAUD, &Baud); 

// write(FileDesc,Ubuff,sizeof(Ubuff)); 
// read(FileDesc,Kbuff,sizeof(Ubuff)); 
// printf("\n The Data read from the Kernel is\n>>>> %s <<<<\n",Kbuff); 
    close(FileDesc); 
} 

J'imprime dans le pilote ce sont la commande et la valeur de l'argument selon lequel imprimer comme cette

command = 1622004312 1074034688 val = 1622004312 

Donc envoyé la commande est égal à l'argument que j'ai envoyé. Pourquoi cela se passe-t-il?

+0

en C, lors de la compilation, activez toujours tous les avertissements, puis corrigez ces avertissements. (pour 'gcc', utilisez au minimum:' -Wall -Wextra -pedantic' J'utilise aussi: '-Wconversion -std = gnu99') – user3629249

+0

le fichier .c manque l'instruction:' #include 'pour de telles choses comme la fonction: 'exit()'. Le fichier driver.c manque l'instruction: '#include ' pour la fonction: 'ioctl()' et l'instruction: '#include pour la fonction:' close() 'Le fichier d'en-tête manque le 'include nécessaire Les instructions 'guard' – user3629249

+0

dans cette instruction: 'printf ("% d% d \ n ", SET_BAUD, &Baud);' le troisième paramètre ne correspond pas à la deuxième spécification de format dans la chaîne de format. – user3629249

Répondre

0

J'ai utilisé un prototype IOCTL plus ancien dans mon pilote. il devrait être de ce type

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) 
static int my_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) 
#else 
static long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 
#endif 

Dans mon cas contre mon noyau

static long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 

est le type correct.