【问题标题】:Linux Kernel write() and read() functionLinux 内核 write() 和 read() 函数
【发布时间】:2017-01-13 23:52:04
【问题描述】:

您好,我需要一些关于学校代码的帮助。

读取函数不应该return 0所以老师告诉我们使用wait_event_interruptible

我的问题是当我想在控制台中使用(例如)命令尝试它时:

echo 1234 > ringdev # my character device
echo 5 > ringdev 
cat ringdev

我只得到一个结果:5

我想得到一个结果:

1234 5

全局变量:

 static char ringdev_buf[4096];
 static size_t ringdev_len;

读取函数:

static ssize_t ringdev_read(struct file *filp, char __user *buf, size_t count,
        loff_t *off)
{      
    ssize_t ret = 0;
    while(1) {
        wait_event_interruptible(head,ringdev_len!=0);
        mutex_lock(&ringdev_lock);
        if(ringdev_len!=0) {
            ret = -EFAULT;
            if (copy_to_user(buf, ringdev_buf,ringdev_len)) { // I was trying everything in the ringdev_len position. 
                ret = ringdev_len;
                goto out_unlock;
            }
        }
        mutex_unlock(&ringdev_lock);
    }
    out_unlock:
    mutex_unlock(&ringdev_lock);
    return ret;
}

我试图在函数copy_to_user(buf, ringdev_buf,count) 中输入任何值,但结果始终相同。

static ssize_t ringdev_write(struct file *filp, const char __user *buf,
        size_t count, loff_t *off)
{
    ssize_t ret=0;
    mutex_lock(&ringdev_lock);
    ret=-EFAULT;
    if(ringdev_len + count < sizeof(ringdev_buf)) {
        if (copy_from_user(ringdev_buf+ringdev_len, buf, count)==0) {
            ringdev_len=ringdev_len+count;
            ret=count;
            wake_up_interruptible(&head);
            goto out_unlock;
        }
    } else {
       ret=-ENOSPC;
    }
    out_unlock:
    mutex_unlock(&ringdev_lock);
    return ret;
}

【问题讨论】:

  • 读取应该复制给用户要读取的整个缓冲区,而不仅仅是一个字符。等待时也要注意,等待后条件可能仍然不满足;在这种情况下,您应该返回 -EINTR。在写作方面,事情实际上看起来还不错
  • 另外,我们希望 1234\n5\n 是 echo 命令之后的内容(cat 会在不同的行上显示 1234 和 5)
  • @PaulStelian 发布答案:p.
  • @Stargateur 我只会发布肯定或最有可能是问题的答案,而不是猜测(即使它们是有根据的猜测)
  • 在读取时您返回错误案例的长度?!

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


【解决方案1】:

调用 copy_to_user(buf, ringdev_buf,1) 会导致从 ringdev_buf 到 buf 的 1 字节复制,所以正确,如果要将整个缓冲区复制到用户空间,则必须将其更改为 copy_to_user(buf, ringdev_buf, ringdev_len)

【讨论】:

  • 我已经改了,但还是得到:
  • 我已经改了,但还是只能得到最后一个回显响应
  • 应该是 opy_to_user(buf, ringdev_buf, ringdev_len) 而不是 opy_to_user(buf, ringdev_buf, 4096)
  • 是的,在我的代码中我有 copy_to_user(buf,ringdev_buf,ringdev_len) 并且问题仍然存在。我真的不知道为什么会这样
  • 读取成功时读取函数返回值不正确
【解决方案2】:
 if (copy_to_user(buf, ringdev_buf,ringdev_len)) 

应该是:

 if (copy_to_user(buf, ringdev_buf,ringdev_len)==0)

此外,我没有正确制作 char 设备。但谢谢你的帮助:)。如果有人需要,我可以在这里将我的写/读功能发布在循环缓冲区上,每个想法都可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2012-07-21
    相关资源
    最近更新 更多