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

时间:2014-01-08 21:06:54

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

当我尝试使用以下方法读取字符设备时

 cat /dev/fifodev

我收到来自终端的下一条消息

cat: /dev/fifodev: Invalid argument.

我已经创建了该文件并获得了像这样的权限

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

我的驱动程序的代码是:

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

我在这有什么问题?为什么我不能将cat与/ dev / fifodev文件一起使用?

2 个答案:

答案 0 :(得分:2)

根据您的评论,您遇到的问题似乎是您的应用程序要求将数据读入比您要填充的数据更大的缓冲区。

您需要计算要复制的适当数据量(例如,lengthsize_cbuffer_t(buf)的较小值),并在length的位置使用该值。< / p>

答案 1 :(得分:1)

函数原型缓冲区中的

应该被称为__user,以将其指定为用户空间指针。 read方法的返回是读取的字符串的长度。此函数会一直调用,直到它返回零。 我认为以下代码可以正常工作。

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