简体   繁体   English

使用cat读取字符设备驱动程序时参数无效

[英]Argument invalid when using cat to read a character device driver

When I try to read a char device using: 当我尝试使用以下方法读取char设备时:

 cat /dev/fifodev

I receive the next message from the terminal 我收到来自终端的下一条消息

cat: /dev/fifodev: Invalid argument.

I have created the file and gaven it the permissions like this 我已经创建了文件并授予了这样的权限

sudo mknod /dev/fifodev c 251 0
sudo chmod 666 /dev/fifodev 

The code of my driver is: 我的驱动程序代码是:

/* 
 * Called when a process, which already opened the dev file, attempts to
 * read from it.
 */
static ssize_t device_read(struct file *filp,   /* see include/linux/fs.h   */
               char *buffer,    /* buffer to fill with data */
               size_t length,   /* length of the buffer     */
               loff_t * offset)
{
    char aux[BUF_LEN];

    printk(KERN_ALERT "Entering into device_read");

    if (size_cbuffer_t(buf)<length){
        return -EINVAL;
    }   

    remove_items_cbuffer_t (buf,aux, length);
    copy_to_user(buffer, aux, length);


    printk(KERN_ALERT "Getting out from device_read");

    return length;
}

What problem do I have here? 我这里有什么问题? Why can't i use cat with the /dev/fifodev file? 为什么我不能在/ dev / fifodev文件中使用cat?

Per your comment, the issue you're running into appears to be that your application is requesting to read data into a buffer that is larger than you have data to fill. 根据您的评论,您遇到的问题似乎是您的应用程序正在请求将数据读取到大于要填充的数据的缓冲区中。

You will need to calculate the appropriate amount of data to copy (eg, the smaller value of length and size_cbuffer_t(buf) ), and use that value in the place of length . 您将需要计算要复制的适当数据量(例如, lengthsize_cbuffer_t(buf)的较小值),并使用该值代替length

in the function prototype buffer should be mentioned as __user to specify it as userspace pointer. 在函数原型缓冲区中,应将其称为__user,以将其指定为用户空间指针。 Return of the read method is length of the string read. read方法的返回值是读取的字符串的长度。 This functions keeps getting recalled until it returns zero. 该函数会一直被召回,直到返回零为止。 I think following code will work. 我认为以下代码将起作用。

    static ssize_t device_read(struct file *filp,   /* see include/linux/fs.h   */
               char __user *buffer,    /* buffer to fill with data */
               size_t length,   /* length of the buffer     */
               loff_t * offset)
{
    char aux[BUF_LEN];
    int byte_to_read,maxbyte;   
    printk(KERN_ALERT "Entering into device_read");
    /*
    if (size_cbuffer_t(buf)<length){
        return -EINVAL;
    }   
    */
    maxbyte=strlen(buf) - *offset; //considering buf is the pointer where you have data to copy to buffer(userspace)
    byte_to_read=maxbyte>length?length:maxbyte;
    if(byte_to_read==0)
    {
        printk(KERN_ALERT "Allready Read\n");
        return 0;
    }
    aux=buf;//as in your code AUX doesn't have anything. i'm supposing you want to copy data to this from buf and then use copy_to_user
    remove_items_cbuffer_t (buf,aux, length); //i have no idea why you have used this but i'm sure this wont create any problem
    copy_to_user(buffer, aux, length); //this will copy your data to userspace


    printk(KERN_ALERT "Getting out from device_read");

    return length;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM