首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从内核驱动程序中触发fops轮询函数

如何从内核驱动程序中触发fops轮询函数
EN

Stack Overflow用户
提问于 2022-02-20 16:22:27
回答 1查看 120关注 0票数 0

我正在开发一个内核驱动程序,它使用调试器将一些spi数据记录在虚拟文件中。

我的主要目标是能够“监听”用户空间中的数据,例如使用$ tail -f /sys/kernel/debug/spi-logs,它使用select等待调试器文件上的新数据。

我在驱动程序中实现了fops轮询函数,当我试图从用户空间获取数据时,即使内核中有可读取的新数据,也不会调用轮询函数。

我假设投票函数永远不会被调用,因为调试器文件从未真正被写入。

我的问题是,当有新数据可用时,是否有一种方法可以从内核空间触发轮询函数?

编辑:添加了一个示例

代码语言:javascript
复制
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/wait.h>
#include <linux/poll.h>

struct module_ctx {
    struct wait_queue_head wq;
};

struct module_ctx module_ctx;

static ssize_t debugfs_read(struct file *filp, char __user *buff, size_t count, loff_t *off)
{
    // simulate no data left to read for now
    return 0;
}

static __poll_t debugfs_poll(struct file *filp, struct poll_table_struct *wait) {
    struct module_ctx *module_hdl;
    __poll_t mask = 0;

    module_hdl = filp->f_path.dentry->d_inode->i_private;
    
    pr_info("CALLED!!!");

    poll_wait(filp, &module_hdl->wq, wait);

    if (is_data_available_from_an_external_ring_buffer())
        mask |= POLLIN | POLLRDNORM;

    return mask;
}

loff_t debugfs_llseek(struct file *filp, loff_t offset, int orig)
{
    loff_t pos = filp->f_pos;

    switch (orig) {
        case SEEK_SET:
            pos = offset;
            break;
        case SEEK_CUR:
            pos += offset;
            break;
        case SEEK_END:
            pos = 0; /* Going to the end => to the beginning */
            break;
        default:
            return -EINVAL;
    }

    filp->f_pos = pos;

    return pos;
}

static const struct file_operations debugfs_fops = {
        .owner = THIS_MODULE,
        .read = debugfs_read,
        .poll = debugfs_poll,
        .llseek = debugfs_llseek,
};

static int __init rb_example_init(void)
{
    struct dentry *file;

    init_waitqueue_head(&module_ctx.wq);

    file = debugfs_create_file("spi_logs", 0666, NULL, &module_ctx,
                               &debugfs_fops);
    if (!file) {
        pr_err("qm35: failed to create /sys/kernel/debug/spi_logs\n");
        return 1;
    }

    return 0;
}

static void __exit

rb_example_exit(void) {

}

module_init(rb_example_init);
module_exit(rb_example_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mihai Pop");
MODULE_DESCRIPTION("A simple example Linux module.");
MODULE_VERSION("0.01");

使用tail -f /sys/kernel/debug/spi_logs,轮询函数永远不会被调用

EN

回答 1

Stack Overflow用户

发布于 2022-02-20 21:32:14

poll的语义是在文件上的编码操作(read和/或write)不需要块而返回时返回。在read操作中,“块”是指:

如果在非阻塞模式下调用-EAGAIN.

  • If

  • ( struct file的字段f_flags有标志O_NONBLOCK集),则返回以阻塞模式调用的read read,然后将线程置于等待状态。

如您所见,您的read函数不遵循该约定并返回0,这意味着EOF。因此,调用者没有理由在此之后调用poll

-f选项在tail中的语义

...当到达文件结束时,不是停止,而是等待.

是关于当read返回0时的情况,但是程序需要等待。

正如您所看到的,poll语义不适合这样的等待。相反,这样的程序使用inotify机制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71196334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档