c-字符内设备驱动程序打印语句,在读取方法中执行无限时间



我正在为字符设备驱动程序编写基本的设备驱动程序模块。我想要以下行为:当我将使用cat /dev/scull从设备文件中读取时,我应该得到设备被打开的次数。为此,我使用变量计数,并在调用开放函数时增加它。我将这个变量存储在私有结构中。我遇到的问题是读取功能

struct scull_dev{
    int x;              /*Private data members*/
    struct cdev cdev;   /*This is character device structure*/
};
ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    struct scull_dev *dev = filp->private_data;
    pr_info("You have opened device %d timesn",dev->x);
    return sizeof(dev->x);
}

打印语句"您已读取设备%d次"正在打印无限次。我必须按Ctr+D才能停止。

我希望输出到cat以及日志文件中。

注意:您得到的输出是无限的,因为您总是返回sizeof。而且,您没有将数据复制到cat的代码。

好吧,我已经把我认为你需要的东西编好了[请原谅一些无端的风格清理]。注意:我没有构建它。我已经对它进行了一些注释,所以这应该会让你开始:

struct scull_dev {
    int x;                              /*Private data members*/
    int rdpend;                         // 1=partial read in progress
    int bufoff;                         // current offset within buffer
    int buflen;                         // remaining length to transfer
    char buf[100];                      // buffer with text to output
    struct cdev cdev;                   /*This is character device structure*/
};
ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
    loff_t *f_pos)
{
    struct scull_dev *dev = filp->private_data;
    ssize_t curlen;
    long err;
    // NOTES:
    // (1) rdpend _must_ be cleared in the device close (and/or) device
    //     open -- we only want _one_ output line per invocation
    // (2) _after_ you get this working, you might move _this_ code block
    //     to the open routine (i.e. the rdpend would not be necessary)
    // (3) leaving it here makes the pr_info and cat output appear closer in
    //     time
    do {
        // only output a single line per open
        if (dev->rdpend)
            break;
        dev->rdpend = 1;
        dev->buflen = snprintf(dev->buf,sizeof(dev->buf),
            "You have opened device %d timesn",dev->x);
        pr_info("%s",dev->buf);
        dev->bufoff = 0;
    } while (0);
    // get length and handle user short read
    // [possibly less than we have--(e.g.) caller's count could be (say) 10
    curlen = dev->buflen;
    if (curlen > count)
        curlen = count;
    do {
        // nothing left to output
        if (curlen <= 0)
            break;
        err = copy_to_user(buf,dev->buf + dev->bufoff,curlen);
        // probably an access violation or segmentation fault, etc.
        if (err < 0) {
            curlen = err;
            break;
        }
        // creep through the buffer
        dev->buflen -= curlen;
        dev->bufoff += curlen;
    } while (0);
    return curlen;
}

提醒:不要忘记在打开和/或关闭时清除rdpend

相关内容

  • 没有找到相关文章

最新更新