1

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

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

在这种情况下,我找不到一个好的做法。有些人谈论有一个字符界面(通过/ dev中的文件)并执行来自用户空间的阻止读取(),因此在读取返回时得到通知。

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

所以我在寻找类似的userland回调函数的方法,能够从一个事件的内核模块调用。

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

谢谢:)

+1

**用户代码不能在中断上下文**中执行。 (用户空间信号处理程序抢占其他代码,但它不是来自内核视图的中断上下文)。因此,您有两种可能的用户通知:1)一个线程,等待某个*阻塞呼叫*或2)*发射一个信号*(例如,* SIGUSR1 *),所以用户空间信号处理程序将被执行。 – Tsyvarev

回答

2

从内核到用户空间中调用当然是可能的,例如生成一个用户态进程(考虑内核启动initudev多一些),或使用IPC(网络链路等)。

然而,这是不是你想要的。

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

事实上,这样的设计是非常普遍,有称为UIO或用户空间I/O(见herehere)的现有框架。

0

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

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

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

0

我终于改变了其他的东西,因为产卵用户级进程太慢,错误可能。

我改变了我的软件设计,使用户空间调用ioctl来完成最后的事件。 ioctl通过等待队列阻塞,在事件队列为空时休眠。

感谢您的回答家伙!