gpt4 book ai didi

linux - 从内核空间到用户空间的事件通知

转载 作者:IT王子 更新时间:2023-10-29 00:53:08 25 4
gpt4 key购买 nike

当内核空间发生事件时,如何通知用户空间应用程序?

当数据到达某个 GPIO 时,硬件会产生一个中断。此数据被复制到内核缓冲区。此时,我希望驱动程序通知应用程序它可以调用 read 函数将数据从内核缓冲区复制到用户空间缓冲区。

我想到了使用epoll方法,但是epoll表示设备是否准备好被读取。我想要的是,epoll 指示何时内核缓冲区已满。

还有,有没有办法修改驱动程序中 poll_wait() 函数的行为?

最佳答案

(已在聊天 session 中回复,但似乎这应该在答案中,所以将其更详细地放在这里。)

poll_wait 所做的是将您的驱动程序添加到用户空间程序正在等待的文件描述符列表中。模式是:

  • 用户程序调用poll/select/epoll_ctl
  • 核心内核调用驱动程序的轮询入口点
  • 驱动程序调用 poll_wait 将其等待队列添加到等待队列列表中(除非 GPIO 数据已经可读,您通过返回值指示)
  • 稍后,当设备中断时,您在等待队列上调用 wake_up,如果它(仍然)在轮询/选择调用中等待,这将解除阻塞
  • 用户态程序唤醒,调用read真正获取数据

IOW,poll_wait 本身不会休眠(或阻塞);它只是将您的设备添加到稍后可能会唤醒进程的程序列表中。 sleep 是在核心内核中完成的(例如,在 select 系统调用中)。这样,用户程序可以使用 select 一次在任意数量的设备上等待。

如果您的用户空间程序在等待期间确实没有任何其他事情可做,那么您可以简单地让用户程序调用读取,并让您的驱动程序设置其等待队列并调用 wait_event_interruptible(或其中之一其他 wait_event_* 变体)。这将阻止进程,直到您的中断处理程序调用 wake_up;那时你从内核缓冲区复制到用户缓冲区。

或者您可以同时支持这两种方法。通常,如果您支持 select 方法,您还会在读取函数中检查 O_NONBLOCK 文件标志,以便用户代码可以选择在读取中阻塞。

是的,ISR 可以调用 wake_up。这是设备 I/O 的常见模式:在“进程上下文”中等待/阻塞,在“中断上下文”中唤醒,然后在返回进程上下文后完成 I/O。

顺便说一句,从驱动程序的角度来看,使用 select、poll 或 epoll 通常是相同的。从用户的角度来看,使用 select 或 poll 更容易一些。这是一个“一次性”交易:“这里有一组文件描述符;阻塞直到其中一个准备好读取(或写入等)或直到超时”。

而对于 epoll,您首先创建一个 epoll 描述符,然后单独添加 I/O 文件描述符。但随后“等待”调用仅指定单个 epoll 描述符。因此,如果您有大量文件描述符要等待,则不必在每个系统调用中指定所有这些文件描述符,从而降低每次 epoll 调用的系统调用开销。

关于linux - 从内核空间到用户空间的事件通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24444670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com