2017-04-15 80 views
0

计算器您好亲爱的参与者投票机制,实施字符设备驱动程序

我新的内核空间开发仍处于道路的起点。 我开发了一个基本的字符设备驱动程序,可以读取打开关闭等。但找不到合适的来源以及如何为Poll/select机制示例进行教程。

我写的代码示例下面查询功能:

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

{

poll_wait(file,&dev_wait,wait); 
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; 
} 

}

它工作正常,但不能一已了解几件事情。

当我打电话从用户空间程序选择为

struct timeval time = {5,0 } ; 
select(fd + 1 , &readfs,NULL,NULL,&time); 

在驱动程序中的功能dev_poll调用一次,并以缓冲大小为零或POLLIN。然后再也没有打过电话。在用户空间中,5秒后程序继续,如果dev_poll返回0. 我无法理解的是在这里,驱动程序代码将如何决定并让用户空间程序,如果缓冲区中有东西可读取5秒,如果它被调用一次并立即返回。

反正在内核模块中收集来自用户空间的timeval参数信息吗?

谢谢你从现在开始。

问候,

回答

0

呼叫poll_wait()实际地的一些等待对象到等待队列,指定为第二个参数。当等待对象被触发时(通过等待队列的wake_up或类似的函数),轮询函数被再次评估。

内核驱动程序不需要麻烦超时:当时间到了,等待对象将自动从等待队列中移除。

+0

非常感谢您的回复,那么我该如何处理让内核在超时时有内存数据的情况? 例如,用户空间呼叫选择时间为5秒超时。 在选择的开始我没有设备中的数据。然后我有2秒的数据。所以我想唤醒用户空间程序。我如何实现这一点? – Ozan

+0

正如答案中所写,当队列变为非空时,您需要调用'wake_up'来获得您正在用于'poll'的等待队列。 – Tsyvarev

0

你好亲爱的好奇的人喜欢我投票。我想出了一个解决方案。

从stackowerflow的另一个话题,一个家伙说,如果内核需要持续的情况,poll_function会被多次调用。所以基本上我实现了这个代码。

当轮询时调用wait_poll(wait_queue_head);当设备具有缓冲数据时(这通常在驱动程序写入功能中)。 用wait_queue_head参数调用wake_up宏。 所以在这个步骤之后再次调用驱动程序的轮询函数。 所以在这里你可以返回你想要返回的任何东西。在这种情况下,POLLIN | POLLRDNORM ..

这是我在驱动程序中写入和轮询的示例代码。

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; 

}