我实现了一个驱动GPIO的内核模块。我为userland提供了通过ioctl对其执行操作的可能性,但我希望更深入并设置一个"通知"系统,内核模块将在检测到的事件上直接联系userland。例如,GPIO上的值更改(已通过内核模块中的中断通知)。
主要目的是避免用户空间中的主动轮询循环,我真的不知道如何连接内核模块和用户空间以保持速度,效率,或多或少被动。
在这种情况下,我无法找到任何良好做法。有些人谈论有一个字符界面(通过/ dev中的文件)并从userland执行阻塞read(),因此在读取返回时会收到通知。
这种方法应该足够好,但是如果GPIO值变化非常快,用户空间可能太慢而无法处理通知,最终会被大量无法处理的通知压垮。
所以我正在寻找像userland回调函数这样的方法,可以在事件中从内核模块调用。
你们认为什么是最好的解决方案?有没有解决这个具体问题的现有方法?
谢谢:)
答案 0 :(得分:2)
从内核到用户空间的调用当然是可能的,例如产生用户空间进程(考虑内核启动init
,udev
等等)或使用IPC(netlink和其他)。
但是,这不是您想要的。
正如人们提到的,要走的路是拥有一个char设备,然后使用标准的和众所周知的select/poll
语义。假设你的用户空间程序设计得很好,我认为你不应该担心这种情况会很慢。
事实上,这种设计非常普遍,以至于存在一个名为UIO或 Userspace I / O 的现有框架(参见here和here)。
答案 1 :(得分:0)
对不起,我不知道你是否可以从内核空间调用userland回调,但你可以让你的用户空间应用程序监听SIGKILL,SIGTERM等不同的信号,你可以发送给用户来自内核空间的空间进程。
还有SIGUSR1和SIGUSR2,它们保留用于自定义使用/实现。您的应用程序可以侦听SIGUSR1和/或SIGUSR2。然后你只需要检查,为什么你会得到通知。
我知道,这不完全是你想要的,但也许它有点帮助。 ;)
答案 2 :(得分:0)
我终于换了别的东西,因为产生用户空间的过程太慢而且很可能错误。
我更改了我的软件设计,使userland调用ioctl来获取最后的事件。 ioctl通过等待队列阻塞,在事件队列为空时休眠。
感谢您的回答!