IOCTL调用无法使用驱动程序

时间:2017-02-27 14:22:25

标签: c linux-kernel linux-device-driver device-driver ioctl

我写了一个IOCTL驱动程序和一个带有包含命令的头文件的相应ioctl应用程序。

#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);

头文件

#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)

c file

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

我在驱动程序中打印像这样打印的参数的命令和值是什么

command = 1622004312 1074034688 val = 1622004312

所以发送命令等于我发送的参数。为什么会这样?

1 个答案:

答案 0 :(得分:0)

我在我的驱动程序中使用了较旧的IOCTL原型。 它应该是这种类型

git archive --remote=ssh://remote_server/remote_repository master | tar -x -C /var/www/public_html

在我的情况下反对我的内核

#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

是正确的类型。