通过等待队列

时间:2016-07-20 23:00:50

标签: linux select linux-kernel linux-device-driver kernel-module

我正在为使用慢速ARM SoC的开发板连接的自定义实验室硬件编写Linux字符驱动程序,并试图从内核空间到用户空间实现合适的通知系统。

基本上,我定期(每10毫秒)从HW读取数据,通过内核空间中运行的一些过滤器处理这些数据(这部分没问题),并在满足某些条件时通知用户空间。我的方法是让用户空间守护程序通过poll()系统调用等待来自驱动程序的通知(自然,因为我还在那里监视网络套接字)。

  • 在驱动程序初始化时,我创建了一个定时器(带有setup_timer),它将调用负责读取硬件的函数,设置用于此的GPIO,并创建一个等待队列({{1}从计时器处理程序发出init_waitqueue_head中的.poll处理程序的信号。这部分似乎没问题。

  • 有一个struct file_operations处理程序可以设置和获取条件,但这部分正在运行。

  • 来自.unlocked_ioctl的{​​{1}}方法只是将状态的单个字节放入用户空间;它永远不会阻止因为总是有效的(包括' W' for"等待来自传感器的更多数据")。

  • 设备打开后,启用计时器。其处理函数在10 ms后调用,从HW读取数据,在过滤器中运行,并将计时器设置为再次运行(使用.read);如果过滤后的数据符合我的条件,则会更改状态,将标记struct file_operations设置为1并使用mod_timer方法从poll_evt_waiting分享与wake_up_interruptible方法共享的队列上的.poll。这个方法只是:

    struct file_operations

问题是:我的用户空间守护程序中的static unsigned int firflt_file_poll(struct file *filp, poll_table *wait) { unsigned int mask = 0; poll_wait(filp, &firflt_queue, wait); if (poll_evt_waiting != 0) { mask = POLLIN | POLLRDNORM; poll_evt_waiting = 0; } return mask; } 从未收到来自驱动程序的通知!我的方法有任何明显的错误吗?特别关于等待队列?我从未实施过"另一方"之前的poll(),并从" Linux设备驱动程序",2005年编辑获得了有关此内容的所有信息。

如果连续读取设备文件描述符,我可以看到用户空间的状态变化,但这会使我的守护进程处于繁忙的循环中,这对于慢CPU来说太过分了。我真的需要让它在投票中等待,直到有新的东西。

此外,我对等待队列执行的唯一操作是使用poll()对其进行初始化,并在状态更改时使用init_waitqueue_head将其唤醒,并将其传递给poll_evt_waiting poll_wait 1}}处理程序。这种方法听起来不错吗?

1 个答案:

答案 0 :(得分:0)

在轮询的队列上调用wake_up_interruptible(),强制.poll方法再次再次调用。仅当 .poll方法返回已设置轮询位的掩码时,用户空间流程才会收到通知

检查您的.poll方法是否实际返回非零掩码。