Select Char设备驱动程序中轮询机制的实现

Select Char设备驱动程序中轮询机制的实现,select,module,linux-kernel,kernel,linux-device-driver,Select,Module,Linux Kernel,Kernel,Linux Device Driver,亲爱的stackoverflow参与者大家好 我对内核空间开发还不熟悉,还处于起步阶段。 我开发了一个基本的字符设备驱动程序,可以读取打开关闭等。但找不到正确的源代码以及如何为轮询/选择机制示例提供教程 我已经为poll函数编写了以下示例代码: static unsigned int dev_poll(struct file * file, poll_table *wait) { } 它工作得很好,但不能忍受一些事情 当我调用从用户空间选择程序时 struct timeval time

亲爱的stackoverflow参与者大家好

我对内核空间开发还不熟悉,还处于起步阶段。 我开发了一个基本的字符设备驱动程序,可以读取打开关闭等。但找不到正确的源代码以及如何为轮询/选择机制示例提供教程

我已经为poll函数编写了以下示例代码:

static unsigned int dev_poll(struct file * file, poll_table *wait)
{

}

它工作得很好,但不能忍受一些事情

当我调用从用户空间选择程序时

    struct timeval time  = {5,0 } ;
select(fd + 1 , &readfs,NULL,NULL,&time);
驱动程序中的dev_poll函数调用一次,并返回零或POLLIN以确定缓冲区大小。然后再也没有打过电话。在用户空间中,5秒钟后,如果dev_poll返回0,程序将继续。 我不明白的是,如果缓冲区中有什么东西在这5秒钟内是可读的,只要调用一次并立即返回,驱动程序代码将如何决定并让用户共享程序

内核模块中是否有收集来自用户空间的timeval参数信息的方法

从现在起谢谢你

关于,

Call
poll\u wait()
实际上将一些wait对象放入waitqueue中,并指定为第二个参数。当wait对象被激发时(通过waitqueue的
wake_up
或类似函数),轮询函数将再次被计算

内核驱动程序不必担心超时:当超时时,wait对象将自动从waitqueue中删除。

Call
poll\u wait()
实际上将一些wait对象放入waitqueue中,指定为第二个参数。当wait对象被激发时(通过waitqueue的
wake_up
或类似函数),轮询函数将再次被计算


内核驱动程序不必担心超时问题:当超时时,wait对象将自动从waitqueue中删除。

您好,亲爱的,像我这样对poll很好奇的人。我想出了一个解决办法

在stackowerflow的另一个主题中,一个家伙说,如果内核需要持续运行,poll_函数会被多次调用。所以基本上我实现了这个代码

当轮询调用call wait_poll(等待队列头)时; 当设备具有缓冲数据时(这通常是在驱动程序写入功能中)。 使用wait_queue_head参数调用wake_up宏。 所以在这一步之后,再次调用驱动程序的poll函数。 所以在这里你可以归还你想要归还的任何东西。在这种情况下,POLLIN | pollrdorm

下面是我在驱动程序中编写和轮询的示例代码

    static unsigned int dev_poll(struct file * file, poll_table *wait)
{
    static int dev_poll_called_count = 0 ;
    dev_poll_called_count ++;
    poll_wait(file,&dev_wait,wait);
    read_wait_queue_length++;
    printk(KERN_INFO "Inside dev_poll called time is : %d read_wait_queue_length %d\n",dev_poll_called_count,read_wait_queue_length);

    printk(KERN_INFO "After poll_wait wake_up called\n");
    if (size_of_message > 0 ){
        printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n");
        return POLLIN | POLLRDNORM;
    }
    else {
        printk(KERN_INFO "dev_poll return 0\n");
        return 0;
    }
}

    static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
    printk(KERN_INFO "Inside write \n");;
    int ret;    
    ret = copy_from_user(message, buffer, len);
    size_of_message = len ;
    printk(KERN_INFO "EBBChar: Received %zu characters from the user\n", size_of_message);
    if (ret)
        return -EFAULT;
    message[len] = '\0';
    printk(KERN_INFO "gelen string %s", message);
    if (read_wait_queue_length)
    {
        wake_up(&dev_wait);
        read_wait_queue_length = 0;
    }
    return len;   

}

你好,亲爱的好奇的人们,像我一样,关于民意调查。我想出了一个解决办法

在stackowerflow的另一个主题中,一个家伙说,如果内核需要持续运行,poll_函数会被多次调用。所以基本上我实现了这个代码

当轮询调用call wait_poll(等待队列头)时; 当设备具有缓冲数据时(这通常是在驱动程序写入功能中)。 使用wait_queue_head参数调用wake_up宏。 所以在这一步之后,再次调用驱动程序的poll函数。 所以在这里你可以归还你想要归还的任何东西。在这种情况下,POLLIN | pollrdorm

下面是我在驱动程序中编写和轮询的示例代码

    static unsigned int dev_poll(struct file * file, poll_table *wait)
{
    static int dev_poll_called_count = 0 ;
    dev_poll_called_count ++;
    poll_wait(file,&dev_wait,wait);
    read_wait_queue_length++;
    printk(KERN_INFO "Inside dev_poll called time is : %d read_wait_queue_length %d\n",dev_poll_called_count,read_wait_queue_length);

    printk(KERN_INFO "After poll_wait wake_up called\n");
    if (size_of_message > 0 ){
        printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n");
        return POLLIN | POLLRDNORM;
    }
    else {
        printk(KERN_INFO "dev_poll return 0\n");
        return 0;
    }
}

    static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
    printk(KERN_INFO "Inside write \n");;
    int ret;    
    ret = copy_from_user(message, buffer, len);
    size_of_message = len ;
    printk(KERN_INFO "EBBChar: Received %zu characters from the user\n", size_of_message);
    if (ret)
        return -EFAULT;
    message[len] = '\0';
    printk(KERN_INFO "gelen string %s", message);
    if (read_wait_queue_length)
    {
        wake_up(&dev_wait);
        read_wait_queue_length = 0;
    }
    return len;   

}

谢谢你的回复,那么我应该如何处理这种情况,当我在超时时间内有可用的数据时,让内核运行呢?例如,用户空间调用选择超时5秒。在“选择”的开头,设备中没有数据。然后我在2秒内得到了数据。所以我想唤醒用户空间程序。我如何实现这一点?如答案中所述,当队列变为非空时,您需要为用于
轮询的waitqueue调用
wake\u
。感谢您的回复,那么我应该如何处理这种情况,以便在超时时间内有可用数据时让内核运行?例如,用户空间调用选择超时5秒。在“选择”的开头,设备中没有数据。然后我在2秒内得到了数据。所以我想唤醒用户空间程序。我如何实现这一点?如答案中所述,当队列变为非空时,您需要为您用于
轮询的等待队列调用
唤醒