无法从char设备读取

时间:2015-03-14 07:23:36

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

我为虚拟字符设备制作了驱动程序,并尝试从设备(文件)中写入和读取数据。我能够写入数据但是在选择读取时,没有任何内容被读取和打印,程序返回:

myapp.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

#define DEVICE "/dev/chardriver"

int main()
{
int i,fd;
char ch,write_buf[100],read_buf[100];

fd=open(DEVICE,O_RDWR);

if(fd==-1)
{
    printf("file %s either does not exist or has been locked by another process\n",DEVICE);
    exit(-1);
}

printf("r=read from device\nw=write to device\nenter command:");
scanf("%c",&ch);

switch(ch)
{
    case 'w':
    printf("enter data:");
    scanf("%s",write_buf);
    write(fd,write_buf,sizeof(write_buf));
    break;

    case 'r':
    read(fd,read_buf,sizeof(read_buf));
    printf("device: %s\n",read_buf);
    break;

    default:
    printf("command not recognized\n");
    break;
}

close(fd);

return 0;
}

终端输出:

anubhav@anubhav-Inspiron-3421:~/Desktop/os$ ./myapp
r=read from device
w=write to device
enter command:w
enter data:hello world
anubhav@anubhav-Inspiron-3421:~/Desktop/os$ ./myapp
r=read from device
w=write to device
enter command:r
device: 
anubhav@anubhav-Inspiron-3421:~/Desktop/os$ 

以下是设备上的权限:

anubhav@anubhav-Inspiron-3421:~/Desktop/os$ ls -l /dev/chardriver
crwxrwxrwx 1 root root 250, 0 Mar 14 10:09 /dev/chardriver

这是我的模块代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h> //provides file operations structures
#include <linux/cdev.h> //helps register char driver
#include <linux/semaphore.h> //to access semaphores
#include <asm/uaccess.h> //copytouser,copyfromuser

//create my device
struct my_device
{
    char data[100];
    struct semaphore sem;
} vdevice;

struct cdev *mcdev; //this is device driver
int majornumber; //majorno from dev_num
int ret;
dev_t dev_num;

#define DEVICE_NAME "mydevice"

int device_open(struct inode *inode,struct file *filp)
{
    if(down_interruptible(&vdevice.sem)!=0)
    {
        printk(KERN_ALERT "can't lock device during open");
        return -1;
    }

    printk(KERN_INFO "opened my device");
    return 0;
}//end device_open

ssize_t device_read(struct file *filp,char* bufstoredata,size_t     bufcount,loff_t* curoffset)
{
    printk(KERN_INFO "Reading from device");
    ret=copy_to_user(bufstoredata,vdevice.data,bufcount);
    return ret;
}

ssize_t device_write(struct file *filp,const char* bufsourcedata,size_t bufcount,loff_t* curoffset)
{
    printk(KERN_INFO "Writing to device");
    ret=copy_to_user(vdevice.data,bufsourcedata,bufcount);
    return ret;
}

int device_close(struct inode *inode,struct file *filp)
{
    up(&vdevice.sem);
    printk(KERN_INFO "device closed");
    return 0;
}

//file  operations structure
struct file_operations fops={
.owner=THIS_MODULE,
.open=device_open,
.release=device_close,
.write=device_write,
.read=device_read
};

static int driver_entry(void)
{
    //registers the functionalities of driver to system

    ret=alloc_chrdev_region(&dev_num,0,1,DEVICE_NAME);

    if(ret<0)
    {
        printk(KERN_ALERT "failed to give major no.");
        return ret;
    }

    majornumber=MAJOR(dev_num);

    printk(KERN_INFO "your major no. is %d",majornumber);

    printk(KERN_INFO "\tuse \"mknod /dev/%s c %d 0\" for device file",DEVICE_NAME,majornumber);

    //create cdev structure
    mcdev=cdev_alloc();
    mcdev->ops=&fops;
    mcdev->owner=THIS_MODULE;
    //now we add cdev to kernel
    ret=cdev_add(mcdev,dev_num,1);
    if(ret<0)
    {
        printk(KERN_ALERT "failed to add cdev to kernel");
        return ret;
    }       

    sema_init(&vdevice.sem,1);

    return 0;
}

static void driver_exit(void)
{
    cdev_del(mcdev);

    unregister_chrdev_region(dev_num,1);

    printk(KERN_ALERT "unloaded module");
}

module_init(driver_entry);
module_exit(driver_exit);

0 个答案:

没有答案