从内核模块

时间:2017-03-09 09:44:11

标签: callback linux-kernel notifications interrupt kernel-module

我实现了一个驱动GPIO的内核模块。我为userland提供了通过ioctl对其执行操作的可能性,但我希望更深入并设置一个"通知"系统,内核模块将在检测到的事件上直接联系userland。例如,GPIO上的值更改(已通过内核模块中的中断通知)。

主要目的是避免用户空间中的主动轮询循环,我真的不知道如何连接内核模块和用户空间以保持速度,效率,或多或少被动。

在这种情况下,我无法找到任何良好做法。有些人谈论有一个字符界面(通过/ dev中的文件)并从userland执行阻塞read(),因此在读取返回时会收到通知。

这种方法应该足够好,但是如果GPIO值变化非常快,用户空间可能太慢而无法处理通知,最终会被大量无法处理的通知压垮。

所以我正在寻找像userland回调函数这样的方法,可以在事件中从内核模块调用。

你们认为什么是最好的解决方案?有没有解决这个具体问题的现有方法?

谢谢:)

3 个答案:

答案 0 :(得分:2)

从内核到用户空间的调用当然是可能的,例如产生用户空间进程(考虑内核启动initudev等等)或使用IPC(netlink和其他)。

但是,这不是您想要的。

正如人们提到的,要走的路是拥有一个char设备,然后使用标准的和众所周知的select/poll语义。假设你的用户空间程序设计得很好,我认为你不应该担心这种情况会很慢。

事实上,这种设计非常普遍,以至于存在一个名为UIO或 Userspace I / O 的现有框架(参见herehere)。

答案 1 :(得分:0)

对不起,我不知道你是否可以从内核空间调用userland回调,但你可以让你的用户空间应用程序监听SIGKILL,SIGTERM等不同的信号,你可以发送给用户来自内核空间的空间进程。

还有SIGUSR1和SIGUSR2,它们保留用于自定义使用/实现。您的应用程序可以侦听SIGUSR1和/或SIGUSR2。然后你只需要检查,为什么你会得到通知。

我知道,这不完全是你想要的,但也许它有点帮助。 ;)

答案 2 :(得分:0)

我终于换了别的东西,因为产生用户空间的过程太慢而且很可能错误。

我更改了我的软件设计,使userland调用ioctl来获取最后的事件。 ioctl通过等待队列阻塞,在事件队列为空时休眠。

感谢您的回答!